[postgreSql] GROUPING SETS/ROLLUP

2022. 5. 24. 16:34DB/PostgreSQL


  Oracle 교육, SQLD책에서만 보던 ROLLUP을 실제로 써봤다.
ROLLUP, CUBE 등의 통계함수가 있다는 것 정도만 알았지 실제로 써본건 처음이다.

SQLD시험을 보기 전에 써봤다면 아마 한번에 합격했겠지?

ROLLUP

ROLLUP은 GROUP BY로 묶어준 뒤 소계 행을 나타내주는 통계함수다.
문법은 어렵지않다. 그냥 딱 보면 어떻게 쓰는지 알 정도!
사실 딱 보면은 아니고 몇 번만 해보면 안다.
무엇보다 실습이 최고👍(⸝⸝⸝°⁻̫° ⸝⸝⸝)

 

SELECT COUNT(1)
  FROM [테이블명]
 WHERE [조건]
 GROUP BY ROLLUP (
       ([COLUMN1])
       ,([COLUMN2],[COLUMN3])
 )


아래는 실제로 적용한 쿼리문들😉(왕뿌듯)

    (SELECT
		'PAY' as "TYPE"
		,COALESCE(PAY_TYPE,'ALL') as "CODE"
		,COUNT(1)	AS "CNT"
		,SUM(SALE_AMT) as "AMT"
	FROM TB_SALE_CUST A
	WHERE  A.PROJECT_CD = 'PM00000001' AND A.DEL_YN = 'N'
	AND SALE_DT =  CURRENT_DATE
	AND CAST(A.STATUS_CD AS INT) BETWEEN 2 AND 4
	GROUP BY ROLLUP(PAY_TYPE)
	ORDER BY PAY_TYPE	
    )
UNION ALL
	(SELECT
		'STATUS' as "TYPE"
		,COALESCE(STATUS_CD ,'ALL') as "CODE"
		,COUNT(1)	AS "CNT"
		,SUM(SALE_AMT) as "AMT"
	FROM TB_SALE_CUST A
	WHERE A.PROJECT_CD = 'PM00000001' AND A.DEL_YN = 'N'
	AND SALE_DT =  CURRENT_DATE
	AND CAST(A.STATUS_CD AS INT) BETWEEN 2 AND 4
	GROUP BY ROLLUP(STATUS_CD)
	ORDER BY STATUS_CD	
    )

 

 

>> 결과

 

  TYPE CODE CNT AMT
1 PAY 01 10 1,661,464
2 PAY 02 3 4,430,800
3 PAY 03 5 11,418,410
4 PAY ALL 18 17,510,674
5 STATUS 02 12 6,085,764
6 STATUS 03 6 11,424,910
7 STATUS ALL 18 17,510,674


GROUPING SETS

찾다보니 GROUPING SET도 써볼만하길래 써봤다. 훨씬 간단하다.

 

SELECT SUM(SALE_AMT), COUNT(1)
  FROM TB_SALE_CUST A
 WHERE A.PROJECT_CD = 'PM00000001' AND A.DEL_YN = 'N'
	   AND SALE_DT =  CURRENT_DATE
	   AND CAST(A.STATUS_CD AS INT) BETWEEN 2 AND 4
 GROUP BY GROUPING SETS(
			(PAY_TYPE),
			(STATUS_CD),
			()
		  )

 

>> 결과

 

  SUM COUNT
1 17,510,674 18
2 4,430,800 3
3 11,418,410 5
4 1,661,464 10
5 6,085,764 12
6 11,424,910 6


GROUPING()

GROUPING("컬럼명") 을 쓰면 해당 컬럼이 Grouping에 사용되었는지 boolean형태로 알 수 있다.

⭐️사용되지 않은 경우 1, 사용된 경우 0을 리턴한다

(아직 헷갈리는 부분)

 

 

SELECT CASE WHEN GROUPING(PAY_TYPE) = 1 and GROUPING(STATUS_CD) = 0 THEN 'STATUS_CD'
			WHEN GROUPING(PAY_TYPE) = 0 and GROUPING(STATUS_CD) = 1 THEN 'PAY_TYPE'
			WHEN GROUPING(PAY_TYPE) = 1 and GROUPING(STATUS_CD) = 1 THEN 'ALL'
			ELSE ''
			END AS "구분"
			,SUM(SALE_AMT), COUNT(1)
FROM TB_SALE_CUST A
WHERE  A.PROJECT_CD = 'PM00000001' AND A.DEL_YN = 'N'
	AND SALE_DT =  CURRENT_DATE
	AND CAST(A.STATUS_CD AS INT) BETWEEN 2 AND 4
GROUP BY GROUPING SETS(
			(PAY_TYPE),
			(STATUS_CD),
			()
		)
ORDER BY "구분"

 

  구분 SUM COUNT
1 ALL 17,510,674 18
2 STATUS_CD 6,085,764 12
3 STATUS_CD 11,424,910 6
4 PAY_TYPE 4,430,800 3
5 PAY_TYPE 11,418,410 5
6 PAY_TYPE 1,661,464 10

 

728x90