SQL에서 소계, 합계를 계산하는 ROLLUP 활용하기
게시일 : 2018년 03월 29일
수정일 : 2019년 01월 29일
# MySQL
# PostgreSQL
# GROUP BY
# ROLLUP
# GROUPING
SQL에서 소계, 합계 계산에 유용한 ROLLUP 활용법에 대해 알아본다.
사용할 데이터는 MySQL reference에서 가져왔다.
year | country | product | profit |
---|---|---|---|
2000 | Finland | Computer | 1500 |
2000 | Finland | Phone | 100 |
2000 | India | Calculator | 150 |
2000 | India | Computer | 1200 |
2000 | USA | Calculator | 75 |
2000 | USA | Computer | 1500 |
2001 | Finland | Phone | 10 |
2001 | USA | Calculator | 50 |
2001 | USA | Computer | 2700 |
2001 | USA | TV | 250 |
ROLLUP 그룹별 집계
ROLLUP을 활용하면 GROUP BY에서 선택한 기준에 따라 합계가 구해진다.
모든 product의 profit 합계와 모든 country의 profit 합계(총합)가 구해진다.
PostgreSQL
PostgreSQL에서는 ROLLUP(컬럼1, 컬럼2) 방식을 사용한다.
SELECT country, product, sum(profit) FROM sales GROUP BY ROLLUP(country, product);
MySQL
MySQL에서는 ROLLUP 대신 WITH ROLLUP을 사용한다.
SELECT country, product, sum(profit) FROM sales GROUP BY country, product WITH ROLLUP;
ROLLUP 적용 전 (왼쪽) VS ROLLUP을 적용한 모습(오른쪽)
country | product | sum(profit) | country | product | sum(profit) | |
---|---|---|---|---|---|---|
Finland | Computer | 1500 | Finland | Computer | 1500 | |
Finland | Phone | 110 | Finland | Phone | 110 | |
India | Calculator | 150 | Finland | NULL | 1610 | |
India | Computer | 1200 | India | Calculator | 150 | |
USA | Calculator | 125 | India | Computer | 1200 | |
USA | Computer | 4200 | India | NULL | 1350 | |
USA | TV | 250 | USA | Calculator | 125 | |
USA | Computer | 4200 | ||||
USA | TV | 250 | ||||
USA | NULL | 4575 | ||||
NULL | NULL | 7535 |
ROLLUP은 집계한 기준값을 NULL값으로 대체한다. COALESCE을 활용하면 원하는 텍스트를 넣을 수 있다.
( MySQL에서는 IFNULL로 대체 가능)
SELECT COALESCE(country,"ALL countries") as country,
COALESCE(product,"ALL products") as product,
sum(profit) FROM sales GROUP BY country, product WITH ROLLUP;
country | product | sum(profit) |
---|---|---|
Finland | Computer | 1500 |
Finland | Phone | 110 |
Finland | ALL products | 1610 |
India | Calculator | 150 |
India | Computer | 1200 |
India | ALL products | 1350 |
USA | Calculator | 125 |
USA | Computer | 4200 |
USA | TV | 250 |
USA | ALL products | 4575 |
ALL countries | ALL products | 7535 |
참고:
mysql 8.0부터는 Oracle처럼 GROUPING 함수를 사용할 수 있다. 결과는 IFNULL을 적용한 쿼리와 같다.
GROUPING(컬럼) 값은 집계가 위치해야 할 ROW(NULL이 표시되는 지점)에서 1 아니면 0을 리턴한다.
IF문을 통해 그 지점을 다른 문자로 대체할 수 있다.
SELECT IF(GROUPING(country),'ALL countries',country),
IF(GROUPING(product),'ALL products',country), SUM(profit)
FROM sales GROUP BY country, product WITH ROLLUP;
References
: