Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

두 테이블의 합집합을 구할때는 UNION을 연산자를 사용합니다.


샘플링 데이터는 JPA를 사용하여 만들었습니다.

  • Address → Address2 로 엔티티복사
  • Address는 100개의 랜덤 주소록생성( 각 프로필은 모두 유니크함 )
  • Address2는 짝수번째 남자 데이터만 복제해서, 여성이 존재하지 않음
  • 3의배수일때는  Address2에 철수만 존재하게함 
  • 샘플 데이터 Address 100개 , Address 67개

Expand
title샘플데이터만들기


Address 데이터를 만드는것은 앞장에서 이미 설명이 되었으며

Address2는 Address데이터에서, 데이터만 약간 변형이 되었습니다.

순차적으로 기술되었기때문에 이해하는데 어려움은 없을듯 보입니다.

Code Block
languagejava
themeEmacs
public void InsertAddressData(){		
	String[] addArray = {
			"서울","대구","부산","창원","마산","제주"				
	};			
	for(int i=0; i<100;i++) {
		Boolean isAddRepo2 = false;
		double random = Math.random();
	    double x = random*100;
	    int y = (int)x + 1; //Add 1 to change the range to 1 - 100 instead of 0 - 99
	    
		Address address = new Address();
		Address2 address2 = new Address2();
		
		address.setAge(y);
		address.setAddress( addArray[i%6] );
		address.setPhoneNbr(String.format("010-3333-1%04d", i));			
		
		if( i%2 == 0 ) {
			address.setName(String.format("민수%d", i+1));
			address.setSex("남");
			//Address2에는 민수가 중복존재함
			isAddRepo2 = true;
			address2.setName(String.format("민수%d", i+1));
			address2.setSex("남");
			address2.setAge(y);
			address2.setAddress( addArray[i%6] );
			address2.setPhoneNbr(String.format("010-3333-1%04d", i));				
		}else {
			address.setName(String.format("영희%d", i+1));
			address.setSex("여");
			//Address2에는 여자가 없음
			isAddRepo2 = false;
		}
		
		if( i%3 == 0) {
			//Address2에는 철수만 있음
			isAddRepo2 = true;
			address2.setName(String.format("철수%d", i+1));
			address2.setSex("남");
			address2.setAge(y);
			address2.setAddress( addArray[i%6] );
			//철수의 전화번호는 다름
			address2.setPhoneNbr(String.format("010-2222-1%04d", i));
		}					
		addressRepo.save(address);
		if(isAddRepo2==true) addressRepo2.save(address2);		
	}					
}
Address1Address2

Image Added

100개

Image Added

67개

 

순수 프로필정보를 가지고 중복체크 여부를 확인하기위한 샘플이며

합집합,교집합,차집합을 설명하기위해 id 값은 select에서 제외하였습니다.


합집합 구하기

Code Block
languagesql
themeEmacs
SELECT address,age,name,phoneNbr,sex FROM db_example.address
UNION
SELECT address,age,name,phoneNbr,sex FROM db_example.address2;


Image Added

100개와 67개의 합집합을 수행하여 167개가 나와야하는데 실제로는 134개의 결과만 나왔습니다.

이것은, 짝수번째(3의배수가 짝수번째가되는상황제외)에서 복제를 하였기때문에 중복을 제거한 합이기 때문입니다.



아쉽게도 JPQL에서 UNION쿼리를 지원하지 않으며, 유니온된 결과는  기존 Entity와 다르기 때문에,

맵핑이 불가능한것은 아니나 어려움이 있습니다. 이때는 SQL Native 쿼리 방식을 사용해야하며

만족스럽지는 못하지만  오브젝트를 변환하는 전통적인 방법을 그대로 사용해해보겠습니다.

JPA에서 UNION 사용하기
Code Block
languagejava
themeEmacs
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) {				
	}
});


결과:

Image Added

Image Added

사용방식에 만족스럽진 못하지만, 동일한 기능을, JPA Repository 인터페이스를 통해 수행하였습니다.



교집합 구하기

Code Block
languagesql
themeEmacs
SELECT address,age,name,phoneNbr,sex FROM db_example.address
INTERSECT
SELECT address,age,name,phoneNbr,sex FROM db_example.address2;

차집합 구하기

Code Block
languagesql
themeEmacs
SELECT address,age,name,phoneNbr,sex FROM db_example.address
EXCEPT
SELECT address,age,name,phoneNbr,sex FROM db_example.address2;