9.1.1 OVER 절 이해하기

분석대상이 되는 레코드 (OVER() 괄호안이 비어있으면 전체레코드가 분석대상이 된다)

-- 분석대상이 되는 레코드 ( COUNT(*) OVER() 제거 )
SELECT  T1.ORD_SEQ ,T1.CUS_ID ,T1.ORD_DT
FROM    T_ORD T1
WHERE   T1.ORD_DT >= TO_DATE('20170301','YYYYMMDD')
AND     T1.ORD_DT < TO_DATE('20170302','YYYYMMDD');

| ORD_SEQ | CUS_ID   | ORD_DT                  |
| ------- | -------- | ----------------------- |
| 442     | CUS_0010 | 2017-03-01 00:00:00.000 |
| 443     | CUS_0020 | 2017-03-01 00:00:00.000 |
| 444     | CUS_0030 | 2017-03-01 00:00:00.000 |
| 445     | CUS_0040 | 2017-03-01 00:00:00.000 |
| 446     | CUS_0050 | 2017-03-01 00:00:00.000 |

조회된 주문 건수를 마지막 컬럼에 추가하는 SQL – 분석함수 사용

-- 총 주문 건수를 마지막 컬럼에 추가하는 SQL
SELECT  
				T1.ORD_SEQ,
				T1.CUS_ID,
				T1.ORD_DT, 
				COUNT(*) OVER() ALL_CNT
FROM    T_ORD T1
WHERE   T1.ORD_DT >= TO_DATE('20170301','YYYYMMDD')
AND     T1.ORD_DT < TO_DATE('20170302','YYYYMMDD');

| ORD_SEQ | CUS_ID   | ORD_DT                  |  | ALL_CNT |
| ------- | -------- | ----------------------- |  | ------- |
| 442     | CUS_0010 | 2017-03-01 00:00:00.000 |  | 5       |
| 443     | CUS_0020 | 2017-03-01 00:00:00.000 |  | 5       |
| 444     | CUS_0030 | 2017-03-01 00:00:00.000 |  | 5       |
| 445     | CUS_0040 | 2017-03-01 00:00:00.000 |  | 5       |
| 446     | CUS_0050 | 2017-03-01 00:00:00.000 |  | 5       |

9.1.2 분석 대상

-- GROUP BY가 없는 SQL
SELECT  T1.ORD_SEQ ,T1.CUS_ID
		,COUNT(*) OVER() ALL_CNT
FROM    T_ORD T1
WHERE   T1.CUS_ID IN ('CUS_0002','CUS_0003')
AND     T1.ORD_DT >= TO_DATE('20170101','YYYYMMDD')
AND     T1.ORD_DT < TO_DATE('20170201','YYYYMMDD')
;

| ORD_SEQ | CUS_ID   |  | ALL_CNT |
| ------- | -------- |  | ------- |
| 1       | CUS_0002 |  | 6       |
| 10      | CUS_0003 |  | 6       |
| 82      | CUS_0002 |  | 6       |
| 91      | CUS_0003 |  | 6       |
| 163     | CUS_0002 |  | 6       |
| 172     | CUS_0003 |  | 6       |
-- GROUP BY가 존재하는 SQL
SELECT  T1.CUS_ID
		,COUNT(*) OVER() ALL_CNT
FROM    T_ORD T1
WHERE   T1.CUS_ID IN ('CUS_0002','CUS_0003')
AND     T1.ORD_DT >= TO_DATE('20170101','YYYYMMDD')
AND     T1.ORD_DT < TO_DATE('20170201','YYYYMMDD')
GROUP BY T1.CUS_ID;

| CUS_ID   |  | ALL_CNT |
| -------- |  | ------- |
| CUS_0002 |  | 2       |
| CUS_0003 |  | 2       |

분석대상이 에러가 없는 정상적인 SQL이어야 한다.

-- 분석대상 SQL 에러가 발생
SELECT  T1.CUS_ID, T1.ORD_AMT
FROM    T_ORD T1
WHERE   T1.CUS_ID IN ('CUS_0002','CUS_0003')
AND     T1.ORD_DT >= TO_DATE('20170101','YYYYMMDD')
AND     T1.ORD_DT < TO_DATE('20170201','YYYYMMDD')
GROUP BY T1.CUS_ID;
-- ORA-00979: not a GROUP BY expression

-- 분석대상 SQL 정상
SELECT  T1.CUS_ID, SUM(T1.ORD_AMT) ORD_AMT
FROM    T_ORD T1
WHERE   T1.CUS_ID IN ('CUS_0002','CUS_0003')
AND     T1.ORD_DT >= TO_DATE('20170101','YYYYMMDD')
AND     T1.ORD_DT < TO_DATE('20170201','YYYYMMDD')
GROUP BY T1.CUS_ID;

| CUS_ID   |  | ORD_AMT |
| -------- |  | ------- |
| CUS_0002 |  | 4830    |
| CUS_0003 |  | 1500    |