본문 바로가기
SQL

[SQL 고득점 Kit] JOIN : 그룹별 조건에 맞는 식당 목록 출력하기

by shur_ 2024. 10. 5.

 

 

https://school.programmers.co.kr/learn/courses/30/lessons/131124

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 


 

 


처음 문제를 봤을 때 쉬워보였는데 생각보다 고생했다.

REST_REVIEW 테이블에서 리뷰를 가장 많이 작성한 회원을 알기 위해 GROUP BY로 MEMBER_ID 별로 묶어서 리뷰 개수가 가장 많은 값이 무엇인지 확인하려고 했다.

예를들어 A와 B가 둘다 5개로 동일하게 가장 많이 리뷰를 작성했을 상황도 고려했다.

 

SELECT
    MEMBER_ID,
    COUNT(REVIEW_ID) AS CNT
FROM REST_REVIEW
GROUP BY MEMBER_ID
ORDER BY CNT DESC
LIMIT 1

 

 

여기까지 뽑아내서 이 쿼리를 서브쿼리로 사용하려고 했는데 여러 시도를 했지만 머리가 돌아가지 않았다.

 

위 쿼리문은 리뷰를 가장 많이 작성한 회원의 리뷰 수를 구하고자 했다.

그래서 COUNT()도 REVIEW_ID를 집계하고있다.

최고 리뷰 수를 가진 회원이 중복되어도 LIMIT 1으로 하나의 값만 뽑아내면 되겠다고 생각했다.

 

SELECT
    MEMBER_ID,
    DENSE_RANK() OVER(ORDER BY COUNT(MEMBER_ID) DESC) AS DENSERANK
FROM REST_REVIEW 
GROUP BY MEMBER_ID

 

 

하지만 위 쿼리는 윈도우 함수를 사용하여 REST_REVIEW 테이블에서 리뷰를 작성한 회원의 행 계수를 카운트하여 순위를 매긴다.

 

GROUP BY로 MEMBER_ID 별로 그룹을 묶음.

집계함수 COUNT()는 이 그룹된 데이터들에 적용되어 계산.

그룹화 된 데이터들에서 COUNT() 한 값들로 순위를 매김.

결국 SELECT 절은 테이블들에서 원하는 COLUMN들을 가져오는 명령.

 

 

 

하지만 아래 쿼리는 조금 다르게 작동하는 것 같았다.

SELECT
    MEMBER_ID,
    DENSE_RANK() OVER(PARTITION BY MEMBER_ID ORDER BY COUNT(MEMBER_ID) DESC) AS DENSERANK
FROM REST_REVIEW 
GROUP BY MEMBER_ID

 

 

MEMBER_ID로 그룹을 묶음

...

모르겠다.

 

 

위 쿼리에서는 MEMBER_ID에 대해 그룹화가 이루어지기 때문에 각 멤버가 유일하게 존재하는 그룹에서 모두 1위.

 

 

 

 

어지쩌지 이해 70%.

SELECT
    MEMBER_ID,
    DENSE_RANK() OVER(ORDER BY CNT DESC) AS DENSERANK
FROM (
SELECT
    MEMBER_ID,
    COUNT(MEMBER_ID) AS CNT
FROM REST_REVIEW 
GROUP BY MEMBER_ID) AS TMP

 

+ FROM절 서브쿼리에는 AS를 붙여야한다.

 

 

최종 쿼리

WITH TEMP AS(
    
    SELECT
        MEMBER_ID,
        DENSE_RANK() OVER(ORDER BY CNT DESC) AS DENSERANK
    FROM (
        SELECT
            MEMBER_ID,
            COUNT(MEMBER_ID) AS CNT
        FROM REST_REVIEW 
        GROUP BY MEMBER_ID) AS TMP)

SELECT
    C.MEMBER_NAME,
    REVIEW_TEXT,
    DATE_FORMAT(REVIEW_DATE, '%Y-%m-%d') AS REVIEW_DATE
FROM
    REST_REVIEW A
    LEFT JOIN TEMP B
    ON A.MEMBER_ID = B.MEMBER_ID
    LEFT JOIN MEMBER_PROFILE C
    ON A.MEMBER_ID = C.MEMBER_ID
WHERE DENSERANK = 1
ORDER BY REVIEW_DATE, REVIEW_TEXT;

 

 

 

 

 


아래는 GROUP BY와 RANK() 관련 함수를 같이 사용하는 경우에 대한 글인데 아직 잘 이해가 안됐다.

 

https://velog.io/@97ss93sh/2023.09.22-TIL-Group-By-Partition-By

 

2023.09.22 TIL - Group By, Partition By

2023.09.22 TIL

velog.io

 

https://boring9.tistory.com/50

 

SQL | MySQL | Window Functions (2) - 집계 함수

01. Window Functions - 윈도우 함수 MySQL 8.0부터 Window Functions이 도입됨 OVER( ) 절을 사용해 지정된 윈도우 프레임에서 연산을 수행하는 함수 OVER ( [PARTITION BY ] [ORDER BY [ASC|DESC], ... ] [] ) 은 윈도우 함수를

boring9.tistory.com

 

 

댓글