COUNT함수는 NULL을 0으로 카운트
아래 SQL문의 결과는 CNT_COL1은0, CNT_ALL은 2 > *은 ROW자체건수를 카운트
SELECT COUNT(COL1) CNT_COL1, COUNT(*) CNT_ALL
FROM (
SELECT NULL COL1 FROM DUAL UNION ALL
SELECT NULL COL1 FROM DUAL
)
COUNT안에서 DISTINCT사용시 중복을 제거하고 COUNT
> COUNT(DISTINCT 컬럼)
컬럼 조합에 따른 종류수, 처음보는 형태 실무에응용해볼만한듯
한번이라도 로그인한고객수, 한번이라도 사용한 이력등등의 데이터 추출시
SELECT COUNT(DISTINCT T1.ORD_ST || '-' || T1.PAY_TP)
FROM T_ORD T1;
SELECT COUNT(*)
FROM (
SELECT DISTINCT T1.ORD_ST, T1.PAY_TP
FROM T_ORD T1
)T2
--한번이라도 로그인한적있는고객의 수
SELECT COUNT(*)
FROM 고객 T1
WHERE EXISTS (SELECT 1
FROM 로그인 A
WHERE T1.고객ID = A.고객ID)
SELECT T0.*
FROM (
SELECT T1.CUS_ID, T1.PAY_TP, SUM(T1.ORD_AMT) ORD_TTL_AMT
FROM T_ORD T1
WHERE T1.ORD_ST = 'COMP'
GROUP BY T1.CUS_ID, T1.PAY_TP
)T0
WHERE T0.ORD_TTL_AMT >= 10000 --인라인뷰안에서 집계한 ORD_TTL_AMT를 FILTER
ORDER BY T0.ORD_TTL_AMT ASC;
SELECT TO_CHAR(T1.ORD_DT, 'YYYYMM') ORD_YM
, T1.CUS_ID
, SUM(T1.ORD_AMT) ORD_AMT
FROM T_ORD T1
WHERE T1.CUS_ID IN('CUS_0001','CUS_0002')
AND T1.ORD_DT >= TO_DATE ('20170301','YYYYMMDD')
AND T1.ORD_DT < TO_DATE('20170501','YYYYMMDD')
GROUP BY TO_CHAR(T1.ORD_DT, 'YYYYMM'), T1.CUS_ID
ORDER BY TO_CHAR(T1.ORD_DT, 'YYYYMM'), T1.CUS_ID;
ROLLUP사용 쿼리 결과
SELECT TO_CHAR(T1.ORD_DT, 'YYYYMM') ORD_YM
, T1.CUS_ID
, SUM(T1.ORD_AMT) ORD_AMT
FROM T_ORD T1
WHERE T1.CUS_ID IN('CUS_0001','CUS_0002')
AND T1.ORD_DT >= TO_DATE ('20170301','YYYYMMDD')
AND T1.ORD_DT < TO_DATE('20170501','YYYYMMDD')
GROUP BY
ROLLUP (TO_CHAR(T1.ORD_DT, 'YYYYMM'), T1.CUS_ID)
ORDER BY TO_CHAR(T1.ORD_DT, 'YYYYMM'), T1.CUS_ID;
ROLLUP의 컬럼순서
NULL이집계된값과 실제 소계값이 헷갈리는 경우가 발생하는데, GROUPING함수는 해당컬럼이 ROLLUP처리되었으면 1, 아니면 0을 반환한다.
아래 SQL의결과를 보면 PAY_TP가 NULL인것과 WAIT의 소계를 GR_PAY_TP컬럼을 통해 알수있다
SELECT T1.ORD_ST, GROUPING(T1.ORD_ST) GR_ORD_ST
,T1.PAY_TP, GROUPING(T1.PAY_TP) GR_PAY_TP
,COUNT(*) ORD_CNT
FROM T_ORD T1
GROUP BY ROLLUP(T1.ORD_ST, T1.PAY_TP);
ROLLUP된컬럼을 다른 값으로 치환할 때는 꼭 GROUPING을 사용해야 한다. 데이터 특성상 NULL 값이 없음을 확신하고 NULL 값을 그대로 치환할 수도 있지만, 혹시라도 나중에 NULL 값이 발생하면 잘못된 결과가 나오게 된다.
GROUPING을 사용해 소계를 TOTAL로 표시하는 SQL
ROLLUP을 중첩괄호로사용할경우 필요한 소계만 뽑을수있다
EX) 전체합계만 뽑고싶을때 GROUP BY ROLLUP((A,B,C,D))
A,B,C,D가 하나의 단위로 ROLLUP되므로 전체합계만 결과에 추가
GROUP BY A,B,C,D,E,F같이 여러 컬럼중 앞쪽 3개컬럼까지의 소계와 전체합계가 필요하다면
소계가 필요없는 D,E,F를 하나로 묶어버리면 된다.
EX) GROUP BY ROLLUP(A,B,C,(D,E,F))