출처: 프로그래머스 고득점 SQL kit 입양시각구하기(1)
https://programmers.co.kr/learn/courses/30/lessons/59412?language=mysql
-- 코드를 입력하세요
SELECT HOUR(DATETIME) AS HOUR, COUNT(*) AS COUNT
FROM ANIMAL_OUTS
WHERE 9 <= HOUR(DATETIME) AND HOUR(DATETIME) < 20
GROUP BY HOUR(DATETIME)
ORDER BY HOUR(DATETIME) ASC;
실수한 점 : 이 때 9 <= HOUR(DATETIME) < 20 으로 했더니 원하는 결과가 나오지 않았다. 범위마다 각각 따로 처리해야 한다.
주의할 점: 내부 처리 순서는
WHERE
->GROUP BY
->HAVING
->SELECT
->ORDER BY
순서이기 때문에 SELECT 에서 'HOUR' 라고 ALIAS 를 붙여도GROUP BY
절에서 사용할 수 없다.
하지만 MySQL 같이 융통성있게 별명을 사용할 수 있게 지원해주는 DB 도 있다. Oracle 에서는 저러면 에러가 난다.
MySQL DB 외에도 모든 DB 에서 작동할 수 있는 쿼리를 짜려고 했기 때문에 GROUP BY 에서 'HOUR' alias 를 일부러 쓰지 않았다.
마지막으로 ORDER BY 로 HOUR(DATETIME) 컬럼을 오름차순으로 정렬했다.
SELECT HOUR(DATETIME) AS HOUR, COUNT(*) AS COUNT
FROM ANIMAL_OUTS
GROUP BY HOUR
HAVING HOUR BETWEEN 9 AND 19
ORDER BY HOUR ASC;
실수한 점: HAVING 구문 안에 HOUR(DATETIME) 을 넣었더니 다음과 같은 오류가 발생했다.
Unknown column 'DATETIME' in 'having clause'
SQL 에서는 기본적으로 GROUP BY 절에 사용 된 컬럼이나 HAVING 구문 뒤에는 집계함수(Aggregate function)가 사용된 컬럼만이 올 수 있다. HOUR 은 산술함수(Arithmetic function)가 사용된 컬럼이라서 오류가 난 것이다.
GROUP BY 의 HAVING 조건절에서는 집계함수를 사용할 수 있지만, WHERE 구에서는 집계함수를 사용할 수 없다.
왜냐면 HAVING 조건절은 같은 그룹 내 여러개의 rows 를 대상으로 '집계' 를 할 수 있지만, WHERE 에는 그룹 자체가 없기 때문에 여러개의 rows 를 집계할 수 없다.
GROUP BY 에서 지정한 열 이외의 열은 집계함수를 사용하지 않은 채 SELECT 구에 지정할 수 없다.