SELECT
FROM
WHERE
GROUP BY
HAVING
ORDER BY
LIMIT
SELECT
FROM
: 어느 테이블을 대상으로 할 것인가?WHERE
: 테이블에서 특정 조건을 만족하는 row들만 선별GROUP BY
: row들을 그루핑 기준대로 그루핑HAVING
: 그루핑 작업 후 생성된 여러 그룹들 중, 특정 조건을 만족하는 그룹들만 선별ORDER BY
: 각 row를 특정 기준에 따라 정렬LIMIT
: 이전 단계까지 조회된 row들 중 일부 row들만 추출그루핑해서 보기
2020_movie_report
테이블이 있고, 4가지 컬럼이 있다.
name
: 영화 이름category
: 영화 장르main_month
: 주로 상영한 달view_count
: 총 관객 수SELECT
category,
main_month,
COUNT(*) AS '영화 수',
SUM(view_count) AS '총 관객 수'
FROM 2020_movie_report
GROUP BY
category,
main_month
HAVING main_month = '5'
AND SUM(view_count) >= 3000000;
ROLLUP
: 세부 그룹들을 좀 더 큰 단위 그룹으로 중간에 합쳐준다.
SELECT
SUBSTRING(address, 1, 2) AS region,
gender,
COUNT(*)
FROM copang_main.member
GROUP BY
SUBSTRING(address, 1, 2),
gender
WITH ROLLUP
HAVING region IS NOT NULL
ORDER BY
region ASC,
gender DESC;
이런 식으로 결과가 나타났다. 서울 NULL 5
는 그루핑인 gender를 고려하지 않은 서울의 총 회원 수를 나타낸다.
GROUP BY
를 통해 region 컬럼와 gender 컬럼을 기준으로 그루핑 했다.
먼저 작성된 region 컬럼이 상위 기준이 된다.
이 상태에서 WITH ROLLUP
을 사용하면 상위 기준 안에서 각 그룹들을 합친 결과들을 출력해준다.
그런데 사실 이 결과는 부분 총계 row가 하나 빠져있는 상태이다.
HAVING region IS NOT NULL
부분을 제거하고 다시 실행하면 아래와 같은 결과가 나타난다.
SELECT
SUBSTRING(address, 1, 2) AS region,
gender,
COUNT(*)
FROM copang_main.member
GROUP BY
SUBSTRING(address, 1, 2),
gender
WITH ROLLUP
ORDER BY
region ASC,
gender DESC;
빨간색 1번 표시를 보면 해당 row는 region 컬럼과 gender 컬럼을 고려하지 않은 부분의 총계, 전체 총계를 나타내는 row이다.
HAVING region IS NOT NULL
때문에 address 컬럼이 NULL인 회원들은 결과에서 제외된 것이다.
- 빨간색 1번 : region 컬럼과 gender 컬럼을 그루핑 기준에서 제외한 부분 총계(=전체 총계)
- 파란색 2번 : address 컬럼이 원래 NULL이고 gender 컬럼의 값이 m인 그룹
- 파란색 3번 : address 컬럼이 원래 NULL이고 gender 컬럼의 값이 f인 그룹
- 파란색 4번 : (2번 + 3번) 그룹(=region 컬럼이 NULL이고 gender 컬럼을 고려하지 않은 그룹의 부분 총계)
위의 경우 어떻게 해야 할까 ❓
일단 member 테이블의 row들을 총 3가지 컬럼을 기준으로 그루핑해보자.
SELECT
YEAR(birthday) AS b_year,
YEAR(sign_up_day) AS s_year,
gender,
COUNT(*)
FROM copang_main.member
GROUP BY
YEAR(birthday),
YEAR(sign_up_day),
gender
WITH ROLLUP
ORDER BY b_year DESC;
회색과 보라색 영역에 주목하자.
이 영역들은 모두 생일 연도와 가입 연도의 조합으로 기준했을 때 성별은 구별하지 않은 부분 총계를 나타낸다.
연두색 영역을 보자.
가입 연도와 성별을 따지지 않은, 방금 전보다 더 광범위한 수준의 부분 총계를 나타내는 부분이다.
이렇게 그루핑 기준이 여러 개일 때는 WITH ROLLUP이 점차 넓은 범위의 부분 총계를 보여준다.
빨간색 영역을 보자.
모든 컬럼이 NULL인, 세 가지 기준을 모두 고려하지 않은 부분 총계를 보여준다. 이 테이블의 총 row 수를 나타낸다.
⭐ WITH ROLLUP
이 GROUP BY
뒤에 나오는 그루핑 기준의 등장 순서에 맞춰서 계층적인 부분 총계를 보여준다. ⭐
이 말은 GROUP BY 뒤에 나오는 그루핑 기준의 등장 순서에 따라 WITH ROLLUP이 출력하는 결과가 달라진다는 뜻이다.
SELECT
YEAR(sign_up_day) AS s_year,
gender,
SUBSTRING(address, 1, 2) AS region,
COUNT(*)
FROM copang_main.member
GROUP BY
YEAR(sign_up_day),
gender,
SUBSTRING(address, 1, 2)
WITH ROLLUP
ORDER BY s_year DESC;
주황색 NULL은 부분 총계를 나타내는 row가 아니다. 애초에 region 컬럼에 NULL이 들어 있던 row들의 그룹을 나타내고 있는 것이다.
하늘색 NULL이 부분 총계를 나타낸다.
NULL을 구분할 수 있게 해주는 함수가 바로 GROUPING
이다.
SELECT
YEAR(sign_up_day) AS s_year,
gender,
SUBSTRING(address, 1, 2) AS region,
GROUPING(YEAR(sign_up_day)), GROUPING(gender), GROUPING(SUBSTRING(address, 1, 2)),
COUNT(*)
FROM copang_main.member
GROUP BY
YEAR(sign_up_day),
gender,
SUBSTRING(address, 1, 2)
WITH ROLLUP
ORDER BY s_year DESC;
GROUPING
함수는 그 인자를 그루핑 기준에서 고려하지 않은 부분 총계인 경우에 1을 리턴하고, 그렇지 않은 경우 0을 리턴한다.
원래 NULL이 입력되어 있던 곳은 0이 출력되어있고, 부분 총계를 나타내기 위해 NULL이 쓰인 곳은 1이 출력되었다.
전체 총계를 나타내는 row에서는 모든 GROUPING 함수가 1을 리턴했다는 것을 알 수 있다.