Having
Group by 는 select 로 도출된 결과 집합을 다시 한번 집계하는것이다.
예를 들어
“주문 테이블에서 선박명(ShipName)이 C로 시작하지 않는 선박들의 평균운임(Freight)는 얼마 인가?”
라는 요구는 본질적으로 집계연산이다.
“~별 ~식 이 얼마인가(선박별 평균운임)식의 질문이기 때문이다.”
그러므로 이러한 쿼리는 Group by 로 풀린다.
select ShipName, avg(Freight) as AvgFreight from northwind..orders where ShipName not like 'C%' group by ShipName
여기서 group by 에 한발 앞서서 결과 집합을 다시 필터링 하는 방법을 소개 하고자 한다.
Where 절은 원하는 결과 집합을 찾기 위한 경로를 지시 하는것이다. Top 은 결과 집합 자체를 제한 하기 위해서 사용된다.
이경우는 더이상의 결과 로우들을 결과 집합에 추가하지 않겠다고 한느것이다.
이에반해 Having은 결과 집합은 일단 만들어 놓고 이 결과집합을 다시 한번 필터링 한다. 보다 큰경우는 집계연산식을 조건에 포함하고자 하는 경우에 Having을 사용할수 있다.
where ShipName not like 'C%'
라는 의미는 ShipName이 C로 시작하지 않는 모든 결과 집합을 찾아라는 의미다.
이는 결과 집합을 구성할때 C로 시작하는 모든 노드(Node)는 포기하라는 의미다.
Having도 같은 조건을 포함할수 있다.
select ShipName, avg(Freight) as AvgFreight from northwind..orders group by ShipName Having ShipName not like 'C%'
Having의 올바른 역할은, 집계연산에서만 나타날수 있는 값을 기준으로 결과집합을 생성하는데에 있다고 할수 있다.
“주문테이블에서 선박명(ShipName)이 C로 시작하지 않는 선박들의 평균운임(Freight)는 얼마인가? 다만 평균운임은 30달러 이상어야 한다.”
여기서 “다만” 이란말때문에 Having이 쓰어야만 한다.
인라인뷰를 사용할경우의 쿼리
select * from ( select ShipName, avg(Freight) as AvgFreight from northwind..orders where ShipName not like 'C%' group by ShipName ) as x where x.AvgFreight > 30 Having을 이용한 쿼리 select ShipName, avg(Freight) as AvgFreight from northwind..orders where ShipName not like 'C%' group by ShipName having avg(Freight) >= 30
이 두개의 실행계획은 같다.
No Comments