신이 되고 싶은 갓지이

SQL 코테 연습 프로그래머스 Lv.4 문제풀이 6 본문

SQL

SQL 코테 연습 프로그래머스 Lv.4 문제풀이 6

갓지이 2025. 2. 19. 15:41

1. 주문량이 많은 아이스크림들 조회하기 (JOIN)  정답률 : 73%

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

문제

7월 아이스크림 총 주문량과 상반기의 아이스크림 총 주문량을 더한 값이 큰 순서대로 상위 3개의 맛을 조회하는 SQL 문을 작성해주세요.

 

제일 처음 생각한 방법으로는 각 테이블의 flavor 별로 sum을 구하고, 이후 rank로 3등까지 구할까 하다 너무 많은 서브쿼리를 사용해야해서 order by로 순서를 내려 limit로 3위 까지 자르는것으로 코드를 짰다. 굳이 join을 하면서 서브쿼리를 사용한 이유는 특정 flavor가 7월 또는 상반기에 없을 것을 대비했다. 

-- 1.서브쿼리
SELECT J.FLAVOR
-- ,JULY_TOTAL_ORDER+HALF_TOTAL_ORDER AS SUM -- 잘 오더링 되었는지 확인
FROM (SELECT FLAVOR, SUM(TOTAL_ORDER) AS JULY_TOTAL_ORDER
      FROM JULY
     GROUP BY 1) J
LEFT JOIN (SELECT FLAVOR, SUM(TOTAL_ORDER) AS HALF_TOTAL_ORDER
           FROM FIRST_HALF
          GROUP BY 1) F
    ON J.FLAVOR=F.FLAVOR
ORDER BY JULY_TOTAL_ORDER+HALF_TOTAL_ORDER DESC
LIMIT 3

 

그러나 너무 코드가 긴 느낌이라 아래와같이 union all을 사용해서 두 테이블을 붙이고, flavor별로 total_order을 모두 합했다. 다행히 두 테이블의 칼럼수와 칼럼명이 동일하기에 union all을 사용할 수 있었다. 

-- 2. UNION ALL 사용
SELECT DISTINCT FLAVOR
FROM (SELECT * FROM JULY
     UNION ALL
      SELECT * FROM FIRST_HALF
     ) F
ORDER BY SUM(TOTAL_ORDER) OVER(PARTITION BY FLAVOR) DESC
LIMIT 3

 

 

2. 입양 시각 구하기(2)(GROUP BY)  정답률 : 61%

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

문제

보호소에서는 몇 시에 입양이 가장 활발하게 일어나는지 알아보려 합니다. 0시부터 23시까지, 각 시간대별로 입양이 몇 건이나 발생했는지 조회하는 SQL문을 작성해주세요. 이때 결과는 시간대 순으로 정렬해야 합니다.

 

우선 예시를 보면 아래와 같이 0시부터 23시까지 거래가 없으면 0으로 채워 넣어 0시~23시가 모두 나와있어야한다. 

HOUR COUNT
0 0
1 0
2 0
3 0
4 0
5 0
6 0

이를 위해 우선 0~23이 한 칼럼에 있는 테이블을 만들어줘야하는데 여기서 재귀 CTE가 사용되었다. 임시테이블로 0~23을 만들어주고 입양 테이블을 hour를 기준으로 붙여주고, 공란이면 0을 넣는 COALESCE를 사용해주면 완성이다.

-- 재귀 CTE 사용
WITH RECURSIVE CTE AS (
    SELECT 0 AS HOUR
    UNION ALL
    SELECT HOUR + 1 FROM CTE WHERE HOUR < 23
)
SELECT C.HOUR, COALESCE(COUNT,0) AS COUNT -- 없으면 0으로 
FROM CTE C
LEFT JOIN (SELECT HOUR(DATETIME) AS HOUR, COUNT(*) AS COUNT
            FROM ANIMAL_OUTS
            GROUP BY 1) A
ON A.HOUR=C.HOUR
ORDER BY 1