Search

REMINDER 07-03. 동일한 데이터에서 여러 값을 집계할 때는 FILTER를 활용하자

상황: 한 매장의 2023년 3월 전체 주문 수와 픽업 완료 주문 수를 함께 출력한다.

BAD SQL — 기존 또는 비교 대상

SELECT (SELECT COUNT(*) FROM tr_ord_big AS o WHERE o.shop_id = 'S033' AND o.ord_dtm >= TIMESTAMP '2023-03-01' AND o.ord_dtm < TIMESTAMP '2023-04-01') AS all_cnt, (SELECT COUNT(*) FROM tr_ord_big AS o WHERE o.shop_id = 'S033' AND o.ord_dtm >= TIMESTAMP '2023-03-01' AND o.ord_dtm < TIMESTAMP '2023-04-01' AND o.ord_st = 'PKUP') AS pkup_cnt;
SQL
복사

GOOD SQL — 권장 또는 대안

SELECT COUNT(*) AS all_cnt, COUNT(*) FILTER (WHERE o.ord_st = 'PKUP') AS pkup_cnt FROM tr_ord_big AS o WHERE o.shop_id = 'S033' AND o.ord_dtm >= TIMESTAMP '2023-03-01' AND o.ord_dtm < TIMESTAMP '2023-04-01';
SQL
복사

핵심

•
집계 대상이 같고 조건만 다르면 PostgreSQL의 FILTER (WHERE ...)로 여러 집계를 한 번에 표현할 수 있다.
💡
참고·예외
•
COUNT(CASE WHEN 조건 THEN 1 ELSE 0 END)는 ELSE 0이 NULL이 아니므로 전체 행을 세는 잘못된 작성법이다. 비교할 때는 COUNT(*) FILTER (...) 또는 NULL을 반환하는 CASE를 사용한다. 두 독립 인덱스 조회가 매우 선택적이면 BAD가 더 유리할 수도 있다.