SQL 정리 - GROUP BY

Rael·2022년 10월 12일
0

SQL 정리

목록 보기
3/4

프로그래머스 SQL 고득점 KIT - GROUP BY 편

1. 식품분류별 가장 비싼 식품의 정보 조회하기(Lv.4)

[문제]
FOOD_PRODUCT 테이블에서 식품분류별로 가격이 제일 비싼 식품의 분류, 가격, 이름을 조회하는 SQL문을 작성하라.
식품분류가 '과자', '국', '김치', '식용유'인 경우만 출력하고, 결과는 식품 가격을 기준으로 내림차순 정렬하라.

[풀이]
1.여러 개의 식품분류군 판단
WHERE 절을 사용하여 IN (식품분류군)을 통해 여러 개의 식품분류군을 한 번에 판단할 수 있다.

2.식품분류별로 최댓값 판단
식품분류별로 나누기 위해서, GROUP BYCATEGORY를 묶는다.
그 후, MAX를 사용하여 최댓값을 찾아 그 값을 가진 데이터를 찾아낸다.
값을 가졌는지 판단할 때에는 IN을 사용하여 비교한다.

3.내림차순 정렬
마지막으로 ORDER BY를 사용하여 PRICE DESC로 정렬한다.

SELECT CATEGORY, PRICE AS MAX_PRICE, PRODUCT_NAME
FROM FOOD_PRODUCT
WHERE CATEGORY IN ('과자','국','김치','식용유')
AND PRICE IN (SELECT MAX(PRICE) 
              FROM FOOD_PRODUCT 
              GROUP BY CATEGORY)
ORDER BY PRICE DESC;

2. 즐겨찾기가 가장 많은 식당 정보 출력하기(Lv.3)

[문제]
REST_INFO 테이블에서 음식종류별로 즐겨찾기수가 가장 많은 식당의 음식 종류, ID, 식당 이름, 즐겨찾기수를 조회하는 SQL문을 작성하라.
결과는 음식 종류를 기준으로 내림차순 정렬할 것.

[풀이]
문제 1번과 유사한 형태를 띄고 있으며, 특정 분류군에서 최댓값을 구하는 문제이다.

이런 유형의 문제의 접근법은,
1.GROUP BY를 사용하여 분류군을 그룹으로 묶어낸다.
2.최댓값을 구하기 위한 SUB 구절을 사용한다.
3.최댓값 비교를 위해 IN을 사용한다.

SELECT FOOD_TYPE, REST_ID, REST_NAME, FAVORITES
FROM REST_INFO
WHERE FAVORITES IN (SELECT MAX(FAVORITES)
                    FROM REST_INFO
                    GROUP BY FOOD_TYPE)
GROUP BY FOOD_TYPE
ORDER BY FOOD_TYPE DESC;하세요

3. 고양이와 개는 몇 마리 있을까(Lv.2)

[문제]
동물 보호소에 들어온 동물 중 고양이와 개가 각각 몇 마리인지 조회하는 SQL문을 작성하라. 이때 고양이를 개보다 먼저 조회할 것.

[풀이]
개와 고양이를 분류하여 각 분류군의 개수를 출력해야 한다.

1.개와 고양이를 분류한다.
GROUP BY를 사용하여 분류할 수 있다.

2.분류된 유형의 개수를 구해 고양이부터 출력한다.
유형의 개수COUNT를 통해 구할 수 있다.
Cat이 Dog보다 사전적으로 우선되기 때문에, ANIMAL_TYPEASC 순서로 출력한다.

SELECT ANIMAL_TYPE, COUNT(*) AS count
FROM ANIMAL_INS
GROUP BY ANIMAL_TYPE
ORDER BY ANIMAL_TYPE;

4. 동명 동물 수 찾기(Lv.2)

[문제]
동물 보호소에 들어온 동물 이름 중 두 번 이상 쓰인 이름과 해당 이름이 쓰인 횟수를 조회하는 SQL문을 작성하라.
이때 결과는 이름이 없는 동물은 집계에서 제외하며, 결과는 이름 순으로 조회할 것.

[풀이]
이 문제는 집계가 필요하므로, HAVING 절을 사용해 풀면 간단하다.

HAVING절과 WHERE절 비교

HAVINGWHERE
집계함수 O(조건 비교시 사용)집계함수 X
GROUP BY절 필수GROUP BY 필수 X
SELECT NAME, COUNT(NAME) AS COUNT
FROM ANIMAL_INS
GROUP BY NAME
HAVING COUNT(NAME) >= 2
ORDER BY NAME;

5. 입양 시각 구하기(1)(Lv.2)

[문제]
보호소에서는 몇 시에 입양이 가장 활발하게 일어나는지 알아보려 한다.
09:00부터 19:59까지, 각 시간대별로 입양이 몇 건이나 발생했는지 조회하는 SQL문을 작성하라.
이때 결과는 시간대 순으로 정렬할 것.

[풀이]
1. 시간 형식 변경
2. 변경된 시간 기준으로 그룹화
3. 그룹화된 기준으로 입양 건수 구하기

SELECT TIME_FORMAT(DATETIME, '%H') AS HOUR, COUNT(*) AS COUNT
FROM ANIMAL_OUTS
WHERE TIME_FORMAT(DATETIME, '%H') > 08 AND TIME_FORMAT(DATETIME, '%H') < 20
GROUP BY HOUR
ORDER BY HOUR;

시간이 7, 8, 9와 같은 형식으로 출력되어야 하는데,
07, 08, 09와 같은 형식으로 출력된 것이 문제였다.

찾아보니 TIME_FORMAT 대신, HOUR라는 함수를 사용하면 정답의 형식대로 나온다.
다음은 수정한 코드이다.

SELECT HOUR(DATETIME) AS HOUR, COUNT(*) AS COUNT
FROM ANIMAL_OUTS
WHERE HOUR(DATETIME) > 8 and HOUR(DATETIME) < 20
GROUP BY HOUR
ORDER BY HOUR;

6. 입양 시각 구하기(2)(Lv.4)

[문제]
보호소에서는 몇 시에 입양이 가장 활발하게 일어나는지 알아보려 한다.
0시부터 23시까지, 각 시간대별로 입양이 몇 건이나 발생했는지 조회하는 SQL문을 작성하라.
이때 결과는 시간대 순으로 정렬할 것.

[풀이]
해당 문제는 WITH 절을 사용하여 해결하는 문제이다.
WITH RECURSIVE TIME을 통해 시간 기준을 세워서, 0시부터 23시까지의 시간을 모두 출력할 수 있게끔 한다.
이러한 유형은 공부해두면 시간을 절약할 수 있을 것이다.

WITH RECURSIVE TIME AS(
    SELECT 0 AS H UNION ALL SELECT H+1 FROM TIME WHERE H < 23)
SELECT H AS 'HOUR', COUNT(HOUR(DATETIME)) AS 'COUNT'
FROM TIME 
LEFT JOIN ANIMAL_OUTS 
ON (H=HOUR(DATETIME))
GROUP BY H;

0개의 댓글