아주 옛날에 group by에 대해서 했었습니다. 이것이랑 짝을 맞추는 절이 having 절인데요. 사실 이것이랑 where 절이랑 헷갈리기가 꽤 쉬운 듯 싶습니다. group by는, 어떠한 필드의 값을 기준으로 그룹화를 시키는 것이라고 했습니다.

 

 

[관련글]

[코딩/Sql] - mysql group by 절 : 그룹별로 나눠서 집계한다.

 

 

 꽤 오래전에 썼던 글이군요. 혹여나, group by 절을 모르신다면 보고 오셔도 좋을 듯 싶습니다. having를 알기 위해서는, 비슷하게 생겨먹은 where 하고, having의 해석 순서를 알 필요가 있습니다. 사실, 더 중요한 건 해석 능력입니다. 국어 영역인 셈입니다.

 

 


 먼저 테이블의 필드가 <물건의 종류, 가격> 이라고 해 봅시다. 이 때, 우리는 가격이 25원 이상인 물건이 2개 있는 물건의 종류만 가져 오려고 합니다. 어떻게 하면 좋을까요?

 

 

 테이블은 위와 같습니다. 여기서, 우리는 1차 filtering을 해야 하는데요. 물건 가격이 25 이상인 것만 골라야 할 겁니다. 따라서, 조건절인 where에 물건가격 >= 25가 들어가면 됩니다.

 

 

 그러면 노란 부분만 필터링 되어서 결과 값에 나타납니다. 아직 그룹화가 되기 전입니다. 이것을 어떤 것을 기준으로 나누면 될까요? 물건의 종류, 그러니까 A냐, B냐, C냐에 따라서 나누면 될 거에요.

 

 

 이를 기준으로 나누었습니다. A가 2개, B가 1개, C가 1개가 있습니다. 그룹 함수는 count, sum, max, min, avg 등이 있는데요. 저는 이 중, 가격이 25원 이상인 물건이 2개 이상 있는 물품의 종류를 가져 와야 한다고 했습니다. 그러니까, count를 써야겠네요. 갯수와 관련된 집계 함수이기 때문입니다.

 

 

 그러면 A가 2개, B가 1개, C가 1개가 있다는 것이 group by까지 수행하고 나면 그러한 정보가 얻어질 겁니다. 여기에서, 우리는 2개 이상 있는 A에 대해서만 나오게 하려면, count 값을 가지고 걸어버리면 됩니다. count(*)>1로 해도 무난해요. not null 조건이 붙어 있다면요. 즉, 결과 그룹에 대해서 필터링을 걸 때, having 조건절을 씁니다.

 

 


 또 다른 예제를 보겠습니다.

 

 쿼리를 잘 보면, 그룹화 후에 필터링을 걸어야 하는 조건과, 그룹화 하기 전에 filter를 걸어야 하는 조건이 있다는 것을 알 수 있는데요. 전자는 having 절에, 후자는 where 절에 겁니다. 그러면 이 기준을 어떻게 판단하면 좋을까요? 먼저, 2019년 2학기에 강의를 하셨다는 조건은 그룹화 후에 쓸모가 있나요?

 

 

 이 단계에서 거를 수는 없어 보입니다. 이미 그룹화가 된 경우, A에 대한 데이터가 1개, B에 대한 데이터가 1개, C에 대한 데이터가 2개인데, 그 이후에 2019-1학기에 강의를 했던 정보와, 2019-2학기에 강의를 했던 정보는, 어떻게 얻어야 하나요? 그 전에 걸러져야 합니다. 따라서, where 절에 2019-2학기에 강의를 했는지에 대한 조건이 들어가야 합니다.

 

 

 반대로, 학과 평균 급여는 where 절에 들어갈 수 있을까요? 사실 sub Query를 잘 작성하면 불가능하지는 않지만.. 사실 이것은 학과별로 grouping을 한 결과에 필터링을 해야 하는 조건입니다.

 

 

 따라서, having 조건에 avg(salary) >= 43000이 들어가야 할 겁니다. 당연하게도, 보통 데이터 베이스를 교수 정보랑 수업 정보랑 같이 넣어놓지는 않을 거에요. 왜 그런지는 정규화를 배우시면. 크흠.. 2개의 테이블을 가지고, 자연 조인을 한 다음에, where 절에 2019년 2학기에 강의한 교수들 목록을 뽑아온 다음에, group을 시킬 거에요. 학과별로. 다음에 having절에 avg(salary) 조건을 걸면 되겠네요. 그룹화 시키기 전에 걸어야 하는 조건과, 그룹에서 걸어야 하는 조건을 잘 구분하는 게 중요합니다.

 

 


 countryCode가 있고, 각 나라마다 도시들이 있습니다. 아래 쿼리는 어떻게 처리하면 좋을까요?

 

  도시가 인구가 100만 이상이라는 조건이, 그룹을 하기 전에 필터링이 되야 하나요? 네. 각 나라 코드별로 그룹화를 하고 나서, 인구가 어떠한 도시가 100만 이상이라는 정보는 어떻게 얻을 건가요? 그룹 필터링을 하기 적합하지 않아요. 그러니, 먼저, 인구가 100만 이상이 도시만 걸러내야 합니다. 그 다음에 그룹화를 시켜야 합니다.

 

 

 따라서 쿼리는 이런 식으로 작성하시면 됩니다.

 

 

 그러면 결과는 이런 식으로 나올 건데요. 여기서, 100만 이상인 도시가 3이상인 Country만 뽑으려면 어떻게 해야 할까요? 당연하게도 having 절에 count(Name)>2라는 조건을 추가로 넣어주면 됩니다.