SELECT문은 작성순서와 실행순서가 다르기 때문에 헷갈리지 않게 구분해서 잘 외워야 한다.
💡SELECT문의 작성순서와 실행순서 차이
1. 작성순서:SELECT▶FROM▶WHERE▶ GROUP BY ▶ HAVING ▶ ORDER BY 2. 실행순서:FROM▶ CONNECT BY ▶WHERE▶ GROUP BY ▶ HAVING ▶SELECT▶ ORDER BY
작성할 때는 SELECT를 가장 먼저 쓰지만 실제 실행되는 것은 가장 마지막 쯤이다.
이런 순서가 있기 때문에 COLUMN에 별칭을 지어준 것이 막히는 구절과 안먹히는 구절이 생긴다.
💡 어디서는 별칭을 쓸 수 있고 어디서는 안되고
SELECT FLOOR(AGE/10)*10 AGES, COUNT(AGE) COUNT
FROM MEMBER M
WHERE AGE IS NOT NULL
GROUP BY FLOOR(AGE/10)*10 //여기서는 별칭 안먹힘
ORDER BY AGES; //여기서는 별칭이 먹히는데
FROM->CONNECT BY->WHERE->GROUP BY->HAVING->SELECT->ORDER BY
별칭을 SELECT에서 지어주었기 때문에SELECT 이전에 실행된 것들은 별칭이 먹히지 않는다.
ORDER BY는 SELECT보다 나중에 실행되기 때문에 별칭을 사용할 수 있지만
GROUP BY는 SELECT보다 먼저 실행되기 때문에 별칭을 사용할 수 없다.
이번에는 작성순서를 기억해서 회원별 게시글 수를 조회해보자.
💡 회원별 게시글 수를 조회하자.
SELECT REG_MEMBER_ID MEMBER_ID,
COUNT(REG_MEMBER_ID) REG_COUNT
FROM NOTICE
WHERE REG_MEMBER_ID IS NOT NULL
GROUP BY REG_MEMBER_ID
ORDER BY MEMBER_ID;
AGE는 NULL을 제외하고 다른 값들이 있었기 때문에 NULL이 0처럼 취급되었고 4760이라는 값이 출력되었다.
#GROUP BY
💡 GROUP BY
1. "~별로"라는 의미가 있으면 GROUP BY이다.
2. 전체 레코드를 대상으로 집계하는 것이 아니라 소규모 그룹으로 나눠서 집계하고 싶을 때 사용한다. 집계함수를 통해 얻은 전체 데이터를 그룹별로 세부 분류하고 싶을 때 사용! (EX: 나이대별, 지역별 등..)
3. 이때 GROUP BY로 묶인 열이 아닌 열들은 SELECT 구절에서 사용할 수 없다. 즉, 그룹된 것도 집계된 것도 아닌 다른 컬럼은 SELECT에서 쓸 수 없다.
집계된 단위가 한 단위로 표현되기 때문에, 집계된 것의 그룹 명과 집계된 값은 함께 출력될 수 있지만 그 외의 값은 절대 포함시킬 수 없다. 출처: 뉴렉처(https://www.youtube.com/@newlec1)
분석을 할 때 전체 레코드를 대상으로 할 수도 있지만 어떤 범주, 소규모 그룹(EX: 나이대별, 지역별)을 나눠서 집계하고 싶은 경우에는 GROUP BY 구절을 사용한다.
그렇다면 나이대별(10대, 20대, 30대 별)로 나이가 얼마나 분포되어 있는지 집계해보자.
SELECT할 때 그냥 AGE 그냥 COUNT라고 해서는 원하는 나이대별(그룹별)로 조회가 되지 않는다.
그냥 전체 데이터가 세부적으로 조회되거나(AGE) 일괄조회(COUNT)된다.
반드시GROUP BY로 집계한 녀석들을 뽑아야지만 원하는 모습대로 나온다.
출처: 뉴렉처(https://www.youtube.com/@newlec1)
#HAVING
💡 HAVING
1. GROUP BY를 필터링 할 수 있다. WHERE절에서는 집계함수를 사용할 수 없으므로 집계함수를 사용했을 때 조건을 걸려면 HAVING절을 사용해야 한다. 출처: 뉴렉처(https://www.youtube.com/@newlec1)
※ 왜 WHERE 절에서는 집계함수를 쓸 수 없을까? → 실행순서 때문이다. 출처: 뉴렉처(https://www.youtube.com/@newlec1)
GROUP BY를 통해서 집계한 내용에 대해서 필터링은 어떻게 해야할까?
COUNT로 ID별 게시글 수를 집계하고 게시글 수가 2개 이상인 ID만 출력해보자.
💡 WHERE을 이용해서 GROUP BY로 뽑은 데이터를 필터링 해보자.
SELECT
REG_MEMBER_ID MEMBER_ID,
COUNT(ID) REG_COUNT
FROM NOTICE
WHERE COUNT(ID) >=2
GROUP BY REG_MEMBER_ID
ORDER BY REG_COUNT DESC;
※ 실행순서: FROM▶CONNECT BY▶WHERE▶GROUP BY▶HAVING▶SELECT▶ORDER BY
WHERE은 GROUP BY를 필터링할 수 없다.
그렇다면GROUP BY는 무엇으로 필터링해야할까? 이럴때 등장하는 것이 HAVING이다.
HAVING은 실행순서 상 GROUP BY 다음에 나오기 때문에 이미 집계된 GROUP BY를 필터링할 수 있다.
💡 HAVING을 이용해서 GROUP BY로 뽑은 데이터를 필터링 해보자.
SELECT
REG_MEMBER_ID MEMBER_ID,
COUNT(ID) REG_COUNT
FROM NOTICE
GROUP BY REG_MEMBER_ID
HAVING COUNT(ID) >=2
ORDER BY REG_COUNT DESC;