본문 바로가기

Development Note

Union All 과 Group By 를 써보자

336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
Union 이라는 쿼리문을 처음 배웠을 시절이 정확히 기억이 난다. Intersaction 이라는 교집합과 대조되는 합집합의 의미를 가진 Union 은 두 테이블로 부터 Select 된 결과 값을 합치는 것이다.. 한마디로 두 테이블을 합쳐 준다고 생각하면 쉬울것 같다.

그런데 어제 건드린 쿼리 문에는 Union 이 아니라 Union All 이란 쿼리문이 있었다.

Union 에서는 중복된 레코드 값을 허용하지 않는다. dintinct 와 같은 역할을 한다고 보면 좋겠다. 그래서 인지 중복된 값이 없도록 나옴과 동시에 또 신기한것은 레코드 값들이 정렬이 되어 나온다 -0-.. 그러면 당연히 성능 측면에서는 Union 이 Union All 보다 느릴수 밖에 없겠지요.

Union 을 사용할 때는 제약 사항이 있다. 쿼리문으로 부터 얻어지는 두개 이상의 결과 값으로 나오는 컬럼의 갯수가 같아야 한다. 실제로 두 Select 문을 Union 을 실행하도록 한 쿼리가 있었는데, 가져오는 컬럼 갯수가 달랐더니..

ORA-01789: 질의의 결과 열의 수가 틀립니다.

이렇게 나와버리고 만다.. 꼭 기억해 두고 이런 실수를 되풀이 하지 않도록 한다.. (그치만 실제로는 선택되는 컬럼수가 많아서 좀 애먹었다 ㅠ 프린트로 뽑아서 컬럼 갯수를 세어가면서 확인 했을 정도니까... 내가 머리가 나쁜건가..)

이러고 실제 쿼리문을 날려보니... 그래도 중복된 컬럼들이 등장하기 시작했다... 개월수를 나타내는 부분들이 천차 만별이라 개월수 별로 나오다 보니 딱 두개의 레코드만 나와야 되는데 무려 6개나 나온다. 이번에는 Group By 라는 명령어를 수정해야 한다.

Group By 는 그룹화 한다는 의미가 강하다. 실제로 단어를 직역 해 보아도 그용도를 알 수 있다. 결국 여러 컬럼들의 공통된 집합들, 다시 말해 집계 해야하는 컬럼을 제외한 모든 컬럼들을 모아모아서 테이블의 값들의 총 합계를 낸다고 볼 수 있다.

내가 한 작업도 그의 한 예이다. 실제 도출되는 테이블마다의 3개씩 레코드를 묶어서 선택 되어야 했기 때문이다. 그래서 선택한 것이 Group By 이다. 간단하게 몇개의 컬럼을 제외하니까 금방 합계가 되어진 두 컬럼이 나왔다. 원하는 컬럼을 기준으로 해당 컬럼에 대한 집합화를 한다. 엑셀의 피벗 테이블하고 비슷하다고 하며, 기본키와도 밀접한 관련이 있다고 한다. 보통 기본키를 중심으로 Grouping 하는 경우 중복제거가 될테니.. ^^ Distinct 와 비슷한 역할을 한다고 할 수 있다.

하지만 엄연히 Distinct 하고는 다르다고 한다. 이는 중복제거를 하고 정렬상태로 만들어 해당 컬럼값만 가져오는 것일 뿐이지 Group By 하고는 엄연히 다른것이다.

후후.. 오늘 정리 끗..