602. Friend Requests II: Who Has the Most Friends : leetcode

오유찬·2026년 1월 14일

SQL

목록 보기
45/71
-- requester_id + accepter_id = friends number
-- id, num
WITH id_num AS (
        SELECT  requester_id as id,
                COUNT(*) as num
        FROM RequestAccepted 
        GROUP BY requester_id

        UNION

        SELECT  accepter_id as id,
                COUNT(*) as num
        FROM RequestAccepted
        GROUP BY accepter_id
    )
-- SELECT * FROM id_num

SELECT      id, sum(num) as num 
FROM        id_num
GROUP BY    id
ORDER BY    num desc
LIMIT       1

CTE에서 requester_id로 그룹화한 테이블과 accepter_id로 그룹화한 테이블에 레코드가 {id:17, num:5}가 각각 있는데 UNION 한 뒤에 id로 그룹화하면 id:17, num:10이 되는 게 아니라 id:17, num:5가 되는 것을 확인할 수 있다.

UNION 연산자의 중복 제거 때문인데, UNION 연산자는 중복을 허용하지 않기 때문에 중복을 제거하고 하나만 남긴다. 중복을 허용하고 그대로 유지하고 싶다면 UNION ALL 연산자를 사용해야 한다.

쿼리 최적화를 진행할 때, 중복이 없을 때 UNION ALL을 사용해서 진행하다 보니 이 부분에서 혼동이 왔었다.

CTE를 작성할 때, 그룹화를 해서 집계 함수를 사용할 필요 없이 id만 출력되도록 테이블을 만들고 본 쿼리에서 그룹화하여 세는 게 가장 빠른 쿼리다.

WITH id_num AS (
        SELECT  requester_id as id
        FROM RequestAccepted 
        
        UNION ALL

        SELECT  accepter_id as id
        FROM RequestAccepted
    )

SELECT      id, COUNT(*) as num 
FROM        id_num
GROUP BY    1
ORDER BY    2 desc
LIMIT       1
profile
열심히 하면 재밌다

0개의 댓글