지우너

[프로그래머스 SQL 고득점 Kit] GROUP BY 본문

Problem Solving

[프로그래머스 SQL 고득점 Kit] GROUP BY

지옹 2025. 1. 17. 08:21

 

식품분류별 가장 비싼 식품의 정보 조회하기

더보기

정답 코드

-- FOOD_PRODUCT 테이블에서 식품분류별로 가격이 제일 비싼 식품의 분류, 가격, 이름을 조회
# 식품분류가 '과자', '국', '김치', '식용유'인 경우만 출력
# 결과는 식품 가격을 기준으로 내림차순 정렬해주세요.
SELECT CATEGORY, PRICE AS MAX_PRICE, PRODUCT_NAME
FROM FOOD_PRODUCT
WHERE (CATEGORY, PRICE) IN (
    SELECT CATEGORY, MAX(PRICE) AS MAX_PRICE
    FROM FOOD_PRODUCT
    WHERE CATEGORY IN ('과자', '국', '김치', '식용유')
    GROUP BY CATEGORY
)
ORDER BY MAX_PRICE DESC

 

실패했던 코드

-- FOOD_PRODUCT 테이블에서 식품분류별로 가격이 제일 비싼 식품의 분류, 가격, 이름을 조회
# 식품분류가 '과자', '국', '김치', '식용유'인 경우만 출력
# 결과는 식품 가격을 기준으로 내림차순 정렬해주세요.
SELECT CATEGORY, MAX(PRICE) AS MAX_PRICE, PRODUCT_NAME
FROM FOOD_PRODUCT
WHERE CATEGORY IN ('과자', '국', '김치', '식용유')
GROUP BY CATEGORY
ORDER BY MAX_PRICE DESC

 

실패 원인:

 

MAX(PRICE)는 그룹 내에서 가장 높은 가격을 계산 → CATEGORY별로 계산됨

문제는 PRODUCT_NAME. MAX(PRICE)로 그룹화하면서 해당 그룹에 속하는 제품 중 어떤 PRODUCT_NAME이 가장 높은 가격과 연결되어야 하는지 명확하지 않음.

⇒ 서브쿼리를 이용하여, 카테고리별 MAX_PRICE를 계산하고, 해당 카테고리, MAX_PRICE와 일치하는 컬럼을 찾는다.

 

 

조건에 맞는 사용자와 총 거래금액 조회하기

더보기

내가 푼 코드

-- USED_GOODS_BOARD와 USED_GOODS_USER 테이블
# 완료된 중고 거래의 총금액이 70만 원 이상인 사람의 회원 ID, 닉네임, 총거래금액을 조회
# 결과는 총거래금액을 기준으로 오름차순 정렬
WITH VIP_USER AS(
    SELECT WRITER_ID AS USER_ID, SUM(PRICE) AS TOTAL_SALES
    FROM USED_GOODS_BOARD
    WHERE STATUS='DONE'
    GROUP BY WRITER_ID
    HAVING SUM(PRICE)>=700000
)

SELECT USER_ID, NICKNAME, TOTAL_SALES
FROM VIP_USER
JOIN USED_GOODS_USER USING(USER_ID)
ORDER BY TOTAL_SALES ASC

 

입양시각구하기(2)

더보기

 

실패한 코드

모든 HOUR이 출력되고, 해당하는 컬럼이 없는(count=0인) hour이 0으로 표시되어야 하는데, 실패함.

SELECT HOUR(DATETIME) AS HOUR, COUNT(*) AS COUNT
FROM ANIMAL_OUTS
GROUP BY 1
ORDER BY 1

 

WITH RECURSIVE ____ AS를 이용한 풀이

https://ror-coding.tistory.com/130

WITH RECURSIVE BASE AS(
    SELECT 0 AS HOUR
    
    UNION ALL
    
    SELECT HOUR+1 AS HOUR
    FROM BASE
    WHERE HOUR<23
)

SELECT *
FROM BASE

0~23시까지 잘 출력된다.

 

그냥 JOIN을 하면 FROM절의 테이블과 JOIN절에 공통으로 있는 튜플을 기준으로 합쳐진다.

우리의 경우 0~23 모든 튜플이 필요하기 때문에 왼쪽에 있는 BASE 테이블 튜플을 전부 가져와야 한다.

따라서 LEFT JOIN을 해준다.

-- 보호소에서는 몇 시에 입양이 가장 활발하게 일어나는지
# 0시부터 23시까지, 각 시간대별로 입양이 몇 건이나 발생했는지 조회
# 결과는 시간대 순으로 정렬
WITH RECURSIVE BASE AS(
    SELECT 0 AS HOUR
    
    UNION ALL
    
    SELECT HOUR+1 AS HOUR
    FROM BASE
    WHERE HOUR<23
)

SELECT HOUR, COUNT(ANIMAL_ID) AS COUNT
FROM BASE b
LEFT JOIN ANIMAL_OUTS a ON HOUR(a.DATETIME)=b.HOUR
GROUP BY HOUR
ORDER BY HOUR

 

언어별 개발자 분류하기

더보기

 

GROUP_CONCAT 사용법

https://fruitdev.tistory.com/16

 

https://allinfor.tistory.com/71

 

테이블 중간 점검

-- DEVELOPERS 테이블
# GRADE별 개발자의 정보를 조회
    # GRADE A : Front End 스킬과 Python 스킬을 함께 가지고 있는 개발자
    # GRADE B : C# 스킬을 가진 개발자
    # GRADE C : 그 외의 Front End 개발자
# GRADE가 존재하는 개발자의 GRADE, ID, EMAIL을 조회
# 결과는 GRADE와 ID를 오름차순
SELECT *
FROM DEVELOPERS d
JOIN SKILLCODES s ON(d.SKILL_CODE & s.CODE)=s.CODE
ORDER BY ID