[SQL] GROUP BY 정리

6720·2023년 3월 25일
0

이거 모르겠어요

목록 보기
13/38
  • 이 게시글은 프로그래머스 SQL Kit - GROUP BY를 기준으로 문제에 쓰였던 표현을 정리하며, 그 외의 다른 이론이나 공식을 정리함.
  • MySQL을 기준으로 정리함.

GROUP BY

사용자가 지정한 컬럼의 값이 같은 행들을 모아 그룹을 만들고 그룹별로 검색을 하기 위해 사용함.
from 절과 where 절 뒤에 위치함.

[GROUP BY 절의 문법]

select 컬럼명
from 테이블명
[where 조건식]
[GROUP BY 컬럼 | 표현식]
[HAVING 그룹조건식];

where 절: 전체 데이터를 그룹으로 나누기 전에 행들을 미리 제거
group by 절: group by 절을 통해 소그룹 별 기준을 정한 후, select 절에 집계 함수를 사용
having 절: group by 절에 의해 만들어진 소그룹에 대한 조건 적용

EX) column1이 1인 행의 개수와 2인 행의 개수를 각각 구하시오.
단, column1의 데이터는 1과 2로만 이루어져 있음.

select column1, count(*)
from table_name
group by column1;

HAVING

그룹에 대한 조건을 작성하기 위해 사용.
집계 함수는 where에 사용할 수 없지만, having 절에는 사용할 수 있음.

EX) column1을 그룹화하여 조회하시오. 대신 행의 개수가 3개 이상인 경우에만 출력되도록 하시오.

select column1, count(*)
from table_name
group by column1
having count(*) >= 3;

+) wheregroup by보다 먼저 있어야 하며, havinggroup by보다 나중에 있어야 함.

문제 예시

입양 시간 구하기

시간(H)을 그룹화하여 입양 시간대가 같은 동물들의 마리수 조회하기

select date_format(datetime, "%H") as HOUR, count(*) as COUNT
from animal_outs
group by hour(datetime)
having HOUR >= 9 and HOUR <= 19
order by HOUR;

시간을 그룹화하는데, 마리수가 0마리인 시간대도 조회하도록 함.

set @hour := -1;

select (@hour := @hour + 1) as HOUR, (
	select count(*)
	from animal_outs
	where hour(datetime) = @hour
) as COUNT
from animal_outs
where @hour < 23

가격대 별 상품 개수 구하기

가격대 별 상품개수를 구하는 데, 이 때 그룹화는 최소 금액을 기준으로 작동하도록 함.

select truncate(price, -4) as price_group, count(product_id) as products
from product
group by price_group
order by price_group;

truncate(column1, [option]): 옵션 값에 해당하는 소수점 자리까지 자르라는 의미이며, 해당 문제처럼 -4의 경우는 소수점에서 거슬러 올라와서 천의 자리부터 일의 자리까지 전부 자르라는 의미임.
예를 들어서 column1의 값이 10000이면 1이 될 것이며, 9999이면 0이 될 것임.

년, 월, 성별 별 상품 구매 회원 수 구하기

select year(sales_date) as year, month(sales_date) as month, gender, count(distinct online_sale.user_id) as users
from online_sale
join user_info on online_sale.user_id = user_info.user_id
group by year, month, gender
having gender is not null
order by year, month, gender;

다음처럼 group by는 한 가지만 결정할 수 있는 것이 아니며 2개 이상의 컬럼 그룹화도 가능함.
이렇게 되면 우선 year 컬럼을 기준으로 그룹화되며, 그룹화된 그룹에서 또 month를 기준으로 그룹화됨. gender도 마찬가지로 month로 그룹화된 그룹에서 다시 gender를 기준으로 그룹화됨.

YEARMONTHGENDERUSERS
2022101
2022111
2022212

결과는 대략적으로 다음과 같이 나타남.

참고 자료

책 - 수제비 SQLD

profile
뭐라도 하자

0개의 댓글