[프로그래머스]Oracle SQL_5(Lv4)

2025. 10. 2. 22:32·코딩 테스트/02. SQL

1. 주문량이 많은 아이스크림 조회하기

https://school.programmers.co.kr/learn/courses/30/lessons/133027?language=oracle

방법1) JOIN을 활용한 풀이 

SELECT H.FLAVOR
FROM (SELECT
        FLAVOR,
        SUM(TOTAL_ORDER) AS HALF_ORDER
    FROM FIRST_HALF
    GROUP BY FLAVOR) H
    JOIN (SELECT
            FLAVOR,
            SUM(TOTAL_ORDER) AS JULY_ORDER
        FROM JULY
        GROUP BY FLAVOR) J
        ON H.FLAVOR = J.FLAVOR
ORDER BY H.HALF_ORDER + J.JULY_ORDER DESC
FETCH FIRST 3 ROWS ONLY;

 

방법2) UNION ALL을 활용한 풀이

SELECT flavor
FROM (
  SELECT flavor, total_order FROM first_half
  UNION ALL
  SELECT flavor, total_order FROM july
) t
GROUP BY flavor
ORDER BY SUM(total_order) DESC
FETCH FIRST 3 ROWS ONLY;

POINT!

이번 문제에서는 같은 맛이라도 7월에는 여러 출하 번호로 나뉘어 들어올 수 있다고 문제에서 명시했습니다.
그래서 7월 테이블(JULY) 안에서도 같은 FLAVOR가 여러 행으로 존재할 수 있고, 상반기 테이블과 합치면 더더욱 중복 행이 많아집니다.
우리가 원하는 건 맛(FLAVOR)별 전체 주문량 합계이니까, 중복을 제거하면 안 되고 그대로 합쳐야 해요.
👉따라서 UNION을 쓰면 안 되고 UNION ALL을 써야 맛별 주문량이 제대로 합산됩니다.

 

UNION ALL

개념: 두 결과 집합을 세로로 합치는 연산자

사용 조건 : UNION ALL을 쓰려면 컬럼 개수, 순서, 타입이 일치해야 한다.

UNION / UNION ALL의 조건

 

  • 컬럼 개수가 동일해야 함
    • SELECT 절의 컬럼 개수가 같아야 함
  • 컬럼 순서가 동일해야 함
    • 첫 번째 SELECT의 1번 컬럼 ↔ 두 번째 SELECT의 1번 컬럼
    • 두 번째 SELECT의 2번 컬럼 ↔ 첫 번째 SELECT의 2번 컬럼 … 이렇게 매칭됨
  • 컬럼 타입이 호환 가능해야 함
    • 예: 첫 번째 SELECT에서 숫자, 두 번째 SELECT에서 문자열을 같은 위치에 두면 안 됨

UNION / UNION ALL의 차이

구분 UNION UNION ALL
중복 처리 중복 행을 제거 (DISTINCT) 중복 행을 그대로 포함
정렬 여부 내부적으로 중복 제거를 위해 정렬/해시 연산 수행 정렬 없이 단순히 합침
속도 상대적으로 느림 (중복 제거 작업 추가됨) 빠름 (단순 합치기)
사용 목적 “서로 다른 데이터만 보고 싶을 때” “모든 데이터를 그대로 보고 싶을 때”

 


2. 그룹별 조건에 맞는 식당 목록 출력하기

https://school.programmers.co.kr/learn/courses/30/lessons/131124?language=oracle

핵심 : 리뷰를 가장 많이 작성한 회원의 리뷰들을 조회

RANK() OVER (ORDER BY COUNT(REVIEW_ID) DESC)

GROUP BY MEMBER_ID를 하면 이미 회원별 리뷰 개수가 집계된 상태니까, 그 시점에서 RANK()는 전체 회원을 기준으로 순위를 매기면 된다.

풀이)

WITH T AS (SELECT
      MEMBER_ID,
      COUNT(REVIEW_ID) AS REVIEW_COUNTS,
      RANK() OVER (ORDER BY COUNT(REVIEW_ID) DESC) AS RK
    FROM REST_REVIEW
    GROUP BY MEMBER_ID)
    
SELECT
    M.MEMBER_NAME,
    R.REVIEW_TEXT,
    TO_CHAR(R.REVIEW_DATE, 'YYYY-MM-DD') AS "REVIEW_DATE"
FROM MEMBER_PROFILE M
JOIN REST_REVIEW R
  ON M.MEMBER_ID = R.MEMBER_ID
WHERE M.MEMBER_ID IN (
  SELECT MEMBER_ID
  FROM T
  WHERE RK = 1
)
ORDER BY REVIEW_DATE, REVIEW_TEXT;

POINT

과거에는 MySQL에서 LIMIT 1로 최다 리뷰 회원을 한 명만 선택했는데, 이 방식은 공동 1등이 존재할 때 동점자를 누락시킨다는 한계가 있었습니다.
실제로 데이터를 확인해 보니 최다 리뷰 수가 동일한 회원이 여러 명이었습니다.
그래서 이번에는 회원별 리뷰 수를 집계한 뒤 윈도우 함수 RANK()로 순위를 매겨 RANK = 1인 모든 회원을 대상으로 리뷰를 조회하도록 설계했습니다.
프로그래머스에서는 과거 풀이도 정답 처리되었지만, 요건 충족 관점에서는 이번 접근이 더 정확하다고 판단합니다.

 

 

'코딩 테스트 > 02. SQL' 카테고리의 다른 글

[프로그래머스]Oracle SQL_7(Lv4)  (0) 2025.10.04
[프로그래머스]Oracle SQL_6(Lv4)/UNION ALL과 CONNECT BY  (0) 2025.10.03
[프로그래머스]Oracle SQL_4(Lv4)  (0) 2025.10.02
[프로그래머스]Oracle SQL_3(Lv4)  (0) 2025.09.29
[프로그래머스]Oracle SQL_2(Lv4)  (1) 2025.09.28
'코딩 테스트/02. SQL' 카테고리의 다른 글
  • [프로그래머스]Oracle SQL_7(Lv4)
  • [프로그래머스]Oracle SQL_6(Lv4)/UNION ALL과 CONNECT BY
  • [프로그래머스]Oracle SQL_4(Lv4)
  • [프로그래머스]Oracle SQL_3(Lv4)
Growth DA Log
Growth DA Log
Growth DA Log 님의 블로그 입니다.
  • Growth DA Log
    Growth DA Log님의 블로그
    Growth DA Log
  • 전체
    오늘
    어제
    • 분류 전체보기 (125)
      • TIS_COMPANY (6)
      • 코딩 테스트 (61)
        • 01. Python (3)
        • 02. SQL (58)
      • 데이터 분석 (53)
        • 01. BigQuery (9)
        • 02. GA4 (1)
        • 02-1. GA4를 더 잘 다루기 위한 마케팅 개.. (5)
        • 03. streamlit (5)
        • 04. Git (12)
        • 05. 데이터 엔지니어링 (3)
        • 06. 데이터 모델링 (11)
        • 07. Excel (0)
        • 08. Tableau (4)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    streamlit
    AARRR
    프로그래머스
    DENSE_RANK
    git
    코테
    SQL
    ROW_NUMBER
    윈도우함수
    쿼리테스트
    tableau
    코드잇스프린트후기
    Reset
    이행성
    cross_join
    코딩테스트
    rank
    solvesql
    tableaubootcamp
    revert
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
Growth DA Log
[프로그래머스]Oracle SQL_5(Lv4)
상단으로

티스토리툴바