데이터 분석 - 기초 4

14788 단어 sqlsql

📌 SELECT문 실행 순서

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 : 총 관객 수
  1. category 컬럼, main_month 컬럼을 기준으로 그루핑하고
  2. 그룹들 중에서 주 상영 월이 5월이고, view_count의 합이 3000000(삼백만) 이상인 것들만 선별하세요.
  3. 그리고 category 컬럼, main_month 컬럼, 각 그룹에 속한 row의 개수, 각 그룹의 view_count 합, 이 4가지 컬럼을 조회하세요.
  4. 마지막으로 각 그룹에 속한 row의 개수 컬럼에는 '영화 수'라는 alias를, 각 그룹의 view_count 합 컬럼에는 '총 관객 수'라는 alias를 붙이세요.
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;

  • 서울 m 4
  • 서울 f 1
  • 서울 NULL 5

이런 식으로 결과가 나타났다. 서울 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 컬럼을 고려하지 않은 그룹의 부분 총계)
  1. 원래 region 컬럼이 NULL인 row들은 아예 제외하고(=파란색 2,3,4번은 아예 제외하고)
  2. 부분 총계는 빠짐없이 모두 보고 싶습니다.(=빨간색 1번은 보고 싶습니다)

위의 경우 어떻게 해야 할까 ❓


📌 WITH ROLLUP 심화

  1. GROUP BY 뒤 기준들의 순서에 따라 WITH ROLLUP 결과도 달라진다.

일단 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 ROLLUPGROUP BY 뒤에 나오는 그루핑 기준의 등장 순서에 맞춰서 계층적인 부분 총계를 보여준다. ⭐

이 말은 GROUP BY 뒤에 나오는 그루핑 기준의 등장 순서에 따라 WITH ROLLUP이 출력하는 결과가 달라진다는 뜻이다.

  1. NULL을 나타내기 위한 NULL vs 부분 총계를 나타내기 위한 NULL
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을 리턴했다는 것을 알 수 있다.


좋은 웹페이지 즐겨찾기