[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 수주);
[출처] group by , having에 관하여..|작성자 담화