[SQL] group by , having에 관하여

Posted on 2008. 7. 4. 16:39
Filed Under DB

<group by , having >


--group by , having 예제!!


SELECT  count(*) as cnt, mccompany_tab.code
FROM Product_Tab  inner join Mccompany_tab on product_tab.company_idx = mccompany_tab.idx
group by mccompany_tab.code
having mccompany_tab.code = 'mchd'


1)group by구

group by구를 사용하면, 열의 값에 따라서 행을 그룹화할 수 있다. group by 구는 지정된 열의 값이 같은 행을 모아서, 테이블을 몇 개의 그룹으로 나눈다. 일반적으로 집계함수와 함께 사용하고, 그룹의 집계를 내는데 사용한다.


group by 구문 -> group by <열이름>


-- 그룹 마다의 합계를 구한다.

select 지역명, sum(점포면적)

from 지역

group 지역명


--

지역명     sum(점포면적)

------     -------------

지역1                     1278

지역2                     3547

지역3                     1540

지역4                     2022


--where구나 order by구 에서는 검색조건이나 정렬대상이 되는 열과 출력 대상이 되는 열 사이에 특별한 관계가 없다. 즉, 어떤 열을 기준으로 해서 검색이나 정렬을 해도, 그 열과는 별개로 다른 열을 출력할 수 있다. 그러나 group by 구를 사용하는 경우에는 이 점에 주의할 필요가 있다. select구에 지정한 열에 따라서 쿼리가 에러가 되는 일이 있다.


-- group by 구에 지정되어 있는 열을 select구에 지정한다.

select 지역명, min(점포면적), max(점포면적)

from 지역

group by 지역명


여기서 group by 구에 [지역명] 열을 지정하고, select 구에는 [지역명] 열과 min, max라는 두 개의 집계함수를 지정하고 있다. group by 구에 지정되어 있는 열을 select구에도 지정하고 있는 점에 주의하자!!


-- group by 구에 지정되어 있는 열을 select구에 지정하지 않는다.

select min(점포면적), max(점포면적)

from 지역

group by 지역명


group by 구에서 지정한 열을 반드시 select 구에 지정할 필요는 없다. 이 쿼리에서 그룹화의 대상은 [지역명]열이지만, 출력의 대상은 두 개의 집계함수 뿐이다.


--group by 구에 지정되어 있지 않은 열을 select구에 지정한다.(에러!!)

select 지점명, min(점포면적), max(점포면적)

from 지역

group by 지역명


이 쿼리에서는 [지역명] 열의 값이 같은 행을 그룹화하고 하나의 행으로 통합하려 하고 있다. 그러나 [지점명] 열의 값은 각각의 행에서 다르다. [지역명] 열의 값에 따라서 행을 하나로 통합하려고 해도 그 [지점명]열에 복수의 값을 표시할 수 없다. 그렇기 때문에 에러가 되는 것이다.


2)having구

having구를 사용하면, group by 구에 의해 그룹화된 데이터에 검색 조건을 설정을 설정하고, 데이터를 찾아낼 수 있다. 일반적으로 where구와 group  by 구를 지정하면 검색조건이 실행되고 나서 그룹화가 진행되지만, group by 구와 having구를 지정하면 그룹화가 진행되고 나서 검색 조건이 실행된다.


having구 구문 -> having <검색조건>


--where구 안에서 집계함수를 사용한다. (에러)

select 지역명, avg(점포면적)

from 지역

where avg(점포면적) < 700

group by 지역명


where구 안에서 집계함수를 사용할 수 없다. 원래, 집계함수는 그룹화가 행해지고 나서 값을 반환하는 것이다. 이 쿼리에서는 그룹화가 행해지기 전에 검색조건 내에서 사용되고 있기때문에 정상적으로 실행될 수 없다. 이 같은 경우 having구를 사용한다. 일반적으로 group by 구와 having구를 지정하면 그룹화가 행해지고 나서 검색조건이 실행된다. 그렇기 때문에 검색조건 내에서 집계 함수를 사용해도, 이미 그룹화가 행해지고 있으므로 바르게 실행될 수 있다.


--having구 내에서 집계 함수를 사용한다.

select 지역명, avg(점포면적)

from 지역

group by 지역명

having avg(점포면적) <700


--select문의 구에는 우선 순위가 있다. where구, group구, having구는 이 순서에 따라서 처리된다. 그렇기 때문에 where구와group by구를 지정하면, 검색조건이 실행되고나서 그룹화가 행해진다. 한편 group by 구와 having 구를 지정하면 그룹화가 행해지고 나서 검색조건이 실행된다.


--having구에 복수의 조건을 지정한다.(and), (or, in.... 사용해 보자!)

select 지역명, avg(점포면적), avg(사원수)

from 지역

group by 지역명

having avg(점포면적) > 500 and avg(사원수) > 80


-- having 구에 지정되어 있는 집계함수를 select구에 지정하지 않는다.

select 지역명, avg(사원수), avg(점포면적)

from 지역

group by 지역명

having count(지역명) > 3


여기서는 count 함수를 검색조건으로 사용해서 행을 골라내고 있지만 count 함수 자체를 출력하는 것은 아니다. 이처럼 having 구에서 지정한 집계 함수를 반드시 select 구에서 지정할 필요는 없다.


--group by 구나 having 구의 사용(잘 살펴서 이해하자!!)

select 거래처, avg(수량)

from 수주

group by 거래처

having avg(수량) >

     (selelct avg(수량)

      from 수주);

반응형

About

by 쑤기c

반응형