Page History
...
두 테이블의 합집합을 구할때는 UNION을 연산자를 사용합니다.
샘플링 데이터는 JPA를 사용하여 만들었습니다.
- Address → Address2 로 엔티티복사
- Address는 100개의 랜덤 주소록생성( 각 프로필은 모두 유니크함 )
- Address2는 짝수번째 남자 데이터만 복제해서, 여성이 존재하지 않음
- 3의배수일때는 Address2에 철수만 존재하게함
- 샘플 데이터 Address 100개 , Address 67개
Expand | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
| |||||||||||
Address2는 Address데이터에서, 데이터만 약간 변형이 되었습니다. 순차적으로 기술되었기때문에 이해하는데 어려움은 없을듯 보입니다.
|
순수 프로필정보를 가지고 중복체크 여부를 확인하기위한 샘플이며
합집합,교집합,차집합을 설명하기위해 id 값은 select에서 제외하였습니다.
합집합 구하기
Code Block | ||||
---|---|---|---|---|
| ||||
SELECT address,age,name,phoneNbr,sex FROM db_example.address
UNION
SELECT address,age,name,phoneNbr,sex FROM db_example.address2; |
100개와 67개의 합집합을 수행하여 167개가 나와야하는데 실제로는 134개의 결과만 나왔습니다.
이것은, 짝수번째(3의배수가 짝수번째가되는상황제외)에서 복제를 하였기때문에 중복을 제거한 합이기 때문입니다.
아쉽게도 JPQL에서 UNION쿼리를 지원하지 않으며, 유니온된 결과는 기존 Entity와 다르기 때문에,
맵핑이 불가능한것은 아니나 어려움이 있습니다. 이때는 SQL Native 쿼리 방식을 사용해야하며
만족스럽지는 못하지만 오브젝트를 변환하는 전통적인 방법을 그대로 사용해해보겠습니다.
JPA에서 UNION 사용하기
Code Block | ||||
---|---|---|---|---|
| ||||
public interface AddressRepo2 extends CrudRepository<Address2, Long>{
@Query(value="SELECT address,age,name,phoneNbr,sex FROM db_example.address " +
"UNION " +
"SELECT address,age,name,phoneNbr,sex FROM db_example.address2 ",
nativeQuery = true)
List<?> makeUniOn(); //이 함수를 통해, UNION의 결과를 볼수가 있습니다.
}
List<?> addressUnion = addressRepo2.makeUniOn();
ObjectMapper mapper = new ObjectMapper();
addressUnion.forEach( item ->{
try {
String jsonInString = mapper.writeValueAsString(item);
System.out.println(jsonInString);
}catch(Exception e) {
}
}); |
결과:
사용방식에 만족스럽진 못하지만, 동일한 기능을, JPA Repository 인터페이스를 통해 수행하였습니다.
교집합 구하기
Code Block | ||||
---|---|---|---|---|
| ||||
SELECT address,age,name,phoneNbr,sex FROM db_example.address
INTERSECT
SELECT address,age,name,phoneNbr,sex FROM db_example.address2;
|
차집합 구하기
Code Block | ||||
---|---|---|---|---|
| ||||
SELECT address,age,name,phoneNbr,sex FROM db_example.address
EXCEPT
SELECT address,age,name,phoneNbr,sex FROM db_example.address2;
|