쿼리문의 실행 순서를 정리해보자면 FROM
→ WHERE
→ GROUP BY
→ HAVING
→ SELECT
→ ORDER BY
순서이다. 그래서 데이터의 크기가 크다면 WHERE
절을 통해 데이터의 범위를 줄여주는 게 트랜잭션의 과부하를 줄이는 데에 도움이 된다.
SELECT order_date,
category,
COUNT(*) AS category_number, --카테고리별 주문 개수
SUM(COUNT(*)) OVER (PARTITION BY order_date) AS all_number --날짜별 주문 개수
FROM records
GROUP BY 1,2
보통 GROUP BY를 대신하여 PARTITION BY를 이용하여 그룹별 집계를 구하지만, GROUP BY 후 PARTITION BY를 사용하여 원하는 그룹간 집계를 구할 수 있다. 여기서도 SUM(COUNT(*)) OVER (PARTITION BY order_date)
을 통해 category별 개수와 order_date별 개수를 동일한 수준의 SELECT에서 구할 수 있었다.
SELECT order_date,
category_number as furniture,
ROUND(CAST(category_number AS float)/CAST(all_number AS float)*100,2) AS furniture_pct
FROM(
SELECT order_date,
category,
COUNT(*) AS category_number, --카테고리별 주문 개수
SUM(COUNT(*)) OVER (PARTITION BY order_date) AS all_number --날짜별 주문 개수
FROM records
GROUP BY 1,2)
WHERE category = 'Furniture' AND --카테고리 Furniture만
CAST(category_number AS float)/CAST(all_number AS float)*100 >= 40 AND -- 40% 이상
all_number >= 10 --하루 주문건수 10 이상
ORDER BY ROUND(CAST(category_number AS float)/CAST(all_number AS float)*100,2) DESC, order_date;
제일 앞 SELECT문에서 ROUND(CAST(category_number AS float)/CAST(all_number AS float)*100,2) AS furniture_pct
를 통해 furniture_pct로 alias를 설정했지만 ORDER BY에서 이를 기준으로 정렬하려고 할 땐 alias로 쓰면 인식 못한다. 아직 컬럼 이름으로 인식하기 전이기 때문에 원본 식으로 작성해야한다.