앞전의 SELECT에 이어서 이번 포스팅에서는 GROUP BY
에 대해 알아보겠습니다. GROUP BY
는 SELECT 문에서 사용되는 절 중 하나로, 데이터를 그룹화하고 그룹별로 집계 함수를 사용하여 데이터를 요약할 때 사용됩니다. GROUP BY
를 사용하면 특정 컬럼의 값을 기준으로 데이터를 그룹화하여 해당 그룹별로 집계 함수를 적용할 수 있습니다.
GROUP BY도 마찬가지로 기본 형태를 기억해주세요!
SELECT [열] FROM [테이블] GROUP BY [열]
CAR_RENTAL_COMPANY_CAR
테이블에서 '통풍시트', '열선시트', '가죽시트' 중 하나 이상의 옵션이 포함된 자동차가 자동차 종류 별로 몇 대인지 출력하는 SQL문을 작성해주세요. 이때 자동차 수에 대한 컬럼명은 CARS
로 지정하고, 결과는 자동차 종류를 기준으로 오름차순 정렬해주세요.
우선 테이블은 다음과 같은 필드로 채워져 있습니다.
SELECT * FROM CAR_RENTAL_COMPANY_CAR;
car_id car_type daily_fee options
1 트럭 102000 주차감지센서,열선시트
2 SUV 148000 주차감지센서,후방카메라
3 세단 55000 스마트키,통풍시트,가죽시트
4 SUV 150000 주차감지센서,스마트키,열선시트,후방카메라,가죽시트
5 SUV 127000 주차감지센서,스마트키
6 트럭 133000 주차감지센서,스마트키
7 승합차 150000 스마트키,통풍시트,열선시트,후방카메라
8 트럭 107000 주차감지센서,통풍시트,열선시트
9 SUV 84000 주차감지센서,스마트키
10 세단 162000 주차감지센서,스마트키,후방카메라
11 승합차 122000 열선시트,후방카메라
12 트럭 142000 후방카메라
13 승합차 144000 네비게이션
14 SUV 77000 주차감지센서,스마트키,열선시트,후방카메라
15 승합차 114000 주차감지센서,통풍시트,후방카메라
16 세단 168000 주차감지센서,열선시트,후방카메라
17 SUV 107000 스마트키,후방카메라
18 SUV 22000 주차감지센서,스마트키,열선시트,후방카메라
19 SUV 79000 주차감지센서,스마트키,열선시트,후방카메라
20 트럭 168000 주차감지센서,통풍시트
21 리무진 250000 주차감지센서,스마트키,통풍시트,후방카메라
22 세단 186000 주차감지센서,스마트키,통풍시트
23 세단 50000 스마트키,네비게이션,열선시트
24 세단 184000 주차감지센서,스마트키,열선시트,후방카메라
25 세단 115000 주차감지센서,열선시트
26 SUV 126000 주차감지센서,통풍시트
27 SUV 23000 주차감지센서,스마트키,통풍시트
28 리무진 298000 주차감지센서,스마트키,네비게이션,열선시트,후방카메라,가죽시트
29 SUV 88000 주차감지센서,후방카메라
30 트럭 140000 주차감지센서,스마트키
결과는 다음과 같은 형태로 출력해야 합니다.
CAR_TYPE | CARS |
---|---|
SUV | 2 |
세단 | 1 |
트럭 | 1 |
**SELECT**
CAR_TYPE, COUNT(*) AS
CARS
FROM
CAR_RENTAL_COMPANY_CAR
~~WHERE
OPTIONS LIKE
'%가죽시트%' OR
OPTIONS LIKE
'%열선시트%' OR
OPTIONS LIKE
'%통풍시트%'~~
**WHERE OPTIONS IN**
('%가죽시트%', '%열선시트%', '%통풍시트%')
GROUP BY
CAR_TYPE
ORDER BY
CAR_TYPE ASC;
SELECT
NAME, COUNT(NAME) as
COUNT
FROM
ANIMAL_INS
GROUP BY
NAME
HAVING
COUNT(NAME) >= 2
ORDER BY
NAME;
COUNT( ) 에서 괄호 안에 있는 열이 무엇을 의미하는가?
예를 들어, COUNT(NAME) 하면 NULL을 제외한 행의 개수를 세어줍니다. 위 예제에서는 GROUP BY NAME을 했으므로, 그룹화 된 이름의 개수를 세어주는 것입니다.
HAVING과 WHERE은 어떻게 다른가?
HAVING 절과 WHERE 절은 SQL에서 데이터를 필터링하는 데 사용되는 두 가지 절입니다. 그러나 두 절은 목적과 사용되는 위치에서 차이가 있습니다.
WHERE 절:
SELECT * FROM Students
WHERE Age > 20;
위의 예시에서 WHERE 절은 "Students" 테이블에서 Age 열이 20보다 큰 레코드를 선택합니다.
HAVING 절:
SELECT Department, AVG(Salary) AS AvgSalary
FROM Employees
GROUP BY Department
HAVING AVG(Salary) > 50000;
위의 예시에서 HAVING 절은 "Employees" 테이블에서 Department 별 평균 Salary를 계산한 후, 평균 Salary이 50000보다 큰 그룹을 선택합니다.
요약하면, WHERE 절은 특정 레코드를 선택하는 데 사용되고, HAVING 절은 그룹화된 데이터를 필터링하는 데 사용됩니다. WHERE 절은 데이터를 가져오기 전에 사용되며, HAVING 절은 GROUP BY 이후에 사용됩니다.
09:00부터 19:59까지, 각 시간대별로 입양이 몇 건이나 발생했는지 조회하는 SQL문을 작성해주세요. 이때 결과는 시간대 순으로 정렬해야 합니다.
**SELECT** DATE_FORMAT(DATETIME, '%H') **AS** HOUR, **COUNT(*) AS** COUNT
**FROM** ANIMAL_OUTS
**WHERE** DATE_FORMAT(DATETIME, '%H') **BETWEEN** '09' **AND** '19'
**GROUP BY** DATE_FORMAT(DATETIME, '%H')
**ORDER** **BY** DATE_FORMAT(DATETIME, '%H');
APPOINTMENT
테이블에서 2022년 5월에 예약한 환자 수를 진료과코드 별로 조회하는 SQL문을 작성해주세요. 이때, 컬럼명은 '진료과 코드', '5월예약건수'로 지정해주시고 결과는 진료과별 예약한 환자 수를 기준으로 오름차순 정렬하고, 예약한 환자 수가 같다면 진료과 코드를 기준으로 오름차순 정렬해주세요.
2022년 5월 예약한 환자 수를 진료과코드 별로 조회하는 문제입니다. 이 문장을 통해 2022년 5월은 WHERE, 진료화코드는 GROUP BY로 나타낼 수 있는 것을 확인할 수 있습니다.
SELECT MCDP_CD AS '진료과코드', COUNT(*) AS '5월예약건수'
FROM **APPOINTMENT**
WHERE MONTH(APNT_YMD) = 5 AND YEAR(APNT_YMD) = 2022
GROUP BY MCDP_CD
ORDER BY 5월예약건수 ASC, 진료과코드 ASC;
MONTH()
, YEAR()
을 통해 날짜에 해당하는 정보를 출력할 수 있습니다.상반기 동안 각 아이스크림 성분 타입과 성분 타입에 대한 아이스크림의 총주문량을 총주문량이 작은 순서대로 조회하는 SQL 문을 작성해주세요. 이때 총주문량을 나타내는 컬럼명은 TOTAL_ORDER로 지정해주세요.
위 문제를 통해 아이스크림의 성분 타입에 따라 GROUP BY 하는 것을 유추할 수 있으며, 총 주문량이 작은 순서대로 조회하기 때문에 이는 ORDER BY 를 통해 정렬 기준을 정립할 수 있습니다. 이 문제는 주문 정보를 담은 테이블과 아이스크림 성분에 대한 테이블이 존재합니다.
SELECT i.INGREDIENT_TYPE, SUM(f.TOTAL_ORDER) AS TOTAL_ORDER
FROM FIRST_HALF AS f
JOIN ICECREAM_INFO AS i ON f.FLAVOR = i.FLAVOR
GROUP BY i.INGREDIENT_TYPE
ORDER BY TOTAL_ORDER;
우선 두 개의 테이블을 하나로 합쳐주는 작업이 필요합니다. 여기에서는 FLAVOR이 외래 키로 작동하고 있기 때문에 다음과 같은 명령어를 통해 두 테이블을 합쳐줍니다.
SELECT * FROM FIRST_HALF AS F
JOIN ICECREAM_INFO AS I ON f.FLAVOR = i.FLAVOR;
PRODUCT
테이블에서 만원 단위의 가격대 별로 상품 개수를 출력하는 SQL 문을 작성해주세요. 이때 컬럼명은 각각 컬럼명은 PRICE_GROUP, PRODUCTS로 지정해주시고 가격대 정보는 각 구간의 최소금액(10,000원 이상 ~ 20,000 미만인 구간인 경우 10,000)으로 표시해주세요. 결과는 가격대를 기준으로 오름차순 정렬해주세요.
SELECT
FLOOR((PRICE) / 10000) * 10000 AS PRICE_GROUP,
COUNT(*) AS PRODUCTS
FROM
PRODUCT
GROUP BY
FLOOR((PRICE) / 10000)
ORDER BY
FLOOR((PRICE) / 10000);