프로그래머스_SQL_오답노트_서브쿼리, RANK PATITION BY, GROUP BY, HAVING 오답 이유

HEE·2025년 3월 12일
0

프로그래머스 SQL

목록 보기
9/13
post-thumbnail

프로그래머스 SQL 고득점 KIT 내 SUM,MAX,MIN

Level 3. 물고기 종류 별 대어 찾기

물고기 종류 별로 가장 큰 물고기의 ID, 물고기 이름, 길이를 출력하는 SQL 문을 작성해주세요.

문제 요구사항 분석

  1. 물고기 종류별로
  2. 가장 큰 물고기
  3. ID, 물고기 이름, 길이 출력

정답 해설

  1. 일반적인 WHEN + 서브쿼리
SELECT I.ID, N.FISH_NAME, I.LENGTH
FROM FISH_INFO I 
INNER JOIN FISH_NAME_INFO N ON I.FISH_TYPE = N.FISH_TYPE
WHERE I.LEGTH = 
      (SELECT MAX(FI.LENGTH)
       FROM FISH_NAME FI
       WHERE FI.FISH_TYPE = I.FISH_TYPE)
 ORDER BY ID;
  1. PARTITION BY 사용
SELECT ID, FISH_NAME, LENGTH
FROM (
  SELECT I.ID, N.FISH_NAME, I.LENGTH,
  RANK() OVER (PARTITION BY I.FISH_TYPE ORDER BY I.LENGTH DESC) 
  AS RANKING
  FROM FISH_INFO I  
  INNER JOIN FISH_NAME_INFO N 
  ON I.FISH_TYPE = N.FISH_TYPE
  ) A
WHERE A.RANKING = 1
ORDER BY ID;

1. [WHEN + 서브쿼리] 구문 풀이

  1. FROM FISH_INFO FI
    FISH_INFO 테이블을 가져온다.
  2. WHERE FI.FISH_TYPE = I.FISH_TYPE
    2-1) 현재 메인 쿼리에서 보고 있는 I.FISH_TYPE과 같은 FI.FISH_TYPE만 필터링한다.
    2-2) 즉 메인 쿼리 FISH-TYPE = 0 이면, 서브쿼리 WHERE FISH_TYPE = 0 인 데이터만 가져온다.
    2-3) 자연스럽게 GROUP역할을 해주는 것!
  3. SELECT MAX(FI.LENGTH)
    각 필터링 된 데이터 중 가장 큰 LENGTH값을 찾는다.
  1. 메인쿼리 :
    INNER JOIN으로 연결 ON으로 공통 컬럼 조인 조건 작성.
  2. 서브쿼리 :
    FISH_NAME 테이블만 있어도 됨. (JOIN 안함)
    메인 쿼리에서 사용한 AS를 쓸 수 없어서 서브쿼리에서 다시 AS 지정해줌.
    메인쿼리 FISH_NAME 테이블과 서브쿼리 FISH_NAME테이블을 따로 작성.
  3. WHERE FI.FISH_TYPE = I.FISH_TYPE 의미
    물고기 타입별로 묶는 GROUP BY의 역할을 해줌.

GROUP BY 와 HAVING 이 안되는 이유

  1. GROUP BY
  • 단독 사용시, 그룹별 하나의 행만 남아서 ID, LENGTH가 무작위인 행이 남게됨.
    (PARTITION BY는 그룹을 유지하며 모든 행을 남김.)
  • 서브쿼리에 사용시, 메인쿼리와 연결이 안됨.
  1. HAVING
  • 해석 순서상 너무 뒤에와서 HAVING조건이 의미 없음.
  • HAVING MAX(LENGTH) 와 같은 단순함수는 불완전 조건이라서 안됨.
    HAVING MAX(LENGTH) >50 이와 같이 = > 등의 비교연산자가 반드시 필요함.

WHEN+서브쿼리 방식보다 PATITOIN BY 방식이 대량의 데이터 처리에 더 좋음.

  • RANKDENSE_RANK 혹은 ROW_NUMBER로 변경해서 2, 3순위 구하기도 쉬움.
profile
ALL IS WELL

0개의 댓글