코딩테스트/프로그래머스

SQL 문제 - 동명 동물 수 찾기 (GROUP BY, HAVING)

Debin 2022. 4. 30.
반응형

문제의 링크는 아래와 같습니다.

https://programmers.co.kr/learn/courses/30/lessons/59041

 

코딩테스트 연습 - 동명 동물 수 찾기

ANIMAL_INS 테이블은 동물 보호소에 들어온 동물의 정보를 담은 테이블입니다. ANIMAL_INS 테이블 구조는 다음과 같으며, ANIMAL_ID, ANIMAL_TYPE, DATETIME, INTAKE_CONDITION, NAME, SEX_UPON_INTAKE는 각각 동물의 아이디

programmers.co.kr

 

우리는 같은 이름을 가진 동물의 수를 찾고 싶다. 해결 SQL문은 아래와 같다. 

--정통적인 데이터베이스 답
SELECT NAME, COUNT(NAME) as NUM from ANIMAL_INS 
GROUP BY(NAME)
HAVING COUNT(NAME) > 1
order by(NAME) ASC

--융퉁성 있는 데이터베이스에서 가능한 답
SELECT NAME, COUNT(NAME) as NUM from ANIMAL_INS 
GROUP BY(NAME)
HAVING NUM > 1
order by(NAME) ASC

이번 시간에 HAVING 구와 GROUP BY구에 대해 간단히 공부하고 넘어가겠다.

 

GROUP BY

  • GROUP BY 구를 사용해 그룹화를 진행한다.
  • 그룹화를 통해 집계함수(COUNT)의 활용범위를 넓힐 수 있다.

먼저 위 문제에서 아래와 같은 코드로 진행을 하면 값이 어떻게 나올까?

select name, count(name) as cnt from animal_ins

결과는 아래와 같다. 모든 name을 count 함수를 통해 집계한 것이다.

그러면 어떻게 해야 이름 별로 모아서 집계를 할 수 있을까? 여기서 위 SQL문에 group by를 사용해보자.

select name, count(name) as cnt from animal_ins group by name

결과중에서 일부만 발췌했다.

Lucy 같은 경우에는 cnt가 3인데, 이것은 Lucy라는 이름을 가진 동물이 3마리 있단 것이다.

group by를 사용해 그룹화를 진행하면 지정된 열의 값이 같은 행이 하나의 그룹으로 묶인다.

DISTINCT와 같이 중복을 제거하는 효과도 있다. 

GROUP BY로 묶인 그룹이 하나의 집합으로서 집계 함수(COUNT)의 인자로 넘겨져서 집계 함수가 동작한다.

GROUP BY와 집계함수를 이용해 우리는 Lucy 이름이 3개나 존재한다는 것을 확인할 수 있었다.

HAVING

집계함수는 WHERE 구의 조건식에서 사용할 수 없다. 실제로 그러한 지 확인해보자. 위 문제에서 아래와 같은 SQL문을 입력하자.

오류가 발생한 것을 확인할 수 있다. count(name) 은 cnt인데 집계함수를 where 절에서 사용할 수 없으므로 오류가 발새했다.

에러가 발생한 이유는 GROUP BY와 WHERE 구의 내부 처리 순서와 관계가 있다.

WHERE 구로 행을 검색하는 처리가 GROUP 그룹화하는 처리보다 순서가 앞서기 때문이다. 

SQL 내부 처리 순서는 아래와 같다.

WHERE 구 -> GROUP BY 구 -> SELECT 구 -> ORDER BY 구

 

그렇다면 집계한 결과에서 조건에 맞는 값을 따로 걸러낼 수는 없을까??

물론 가능하다. 여기서 등장하는 것이 바로 HAVING 구다.

HAVING 구를 사용하면 집계 함수를 사용해서 조건식을 지정할 수 있다.

HAVING 구는 GROUP BY 구의 뒤에 기술하며 WHERE구와 동일하게 조건식을 지정할 수 있다. 조건식이 참이면 반환된다.

HAVING 구까지 포함한 SQL 내부 처리 순서는 아래와 같다.

WHERE 구 -> GROUP BY 구 -> HAVING 구 -> SELECT 구 -> ORDER BY 구

 

원래는 HAVING 구가 SELECT구보다 먼저 처리되므로 별명을 사용할 수 없다. (위 예시에서는 count(name) as cnt )

그러나 MySQL 같은 융퉁성 있게 별명을 사용하는 데이터베이스 제품에서는 가능하다.

그래서 필자가 2가지 SQL 풀이를 위에서 적어놨는데, 2번째 풀이가 바로 융퉁성 있는 데이터베이스 제품들에서 가능한 풀이다.

이렇게 HAVING 구에 대한 내용도 알아봤다.

주의할 점

GROUP BY에서 지정한 열 이외의 열은 집계함수를 사용하지 않은 채 SELECT 구에 지정할 수 없다.

 

이상으로 포스팅을 마칩니다. 감사합니다.

 

 

참고 자료

SQL 첫걸음(아사이 아츠시 지음, 박준용 옮김)

반응형

댓글