602. Friend Requests II: Who Has the Most Friends; UNION ALL, LIMIT
1. Problem
누가 가장 많은 친구를 보유하고 있는지, 그리고 그 친구 수는 몇 명인지 찾아야 한다.
- 핵심 난관: 친구 관계는 requester_id(신청자)와 accepter_id(수락자) 두 컬럼에 나뉘어 저장되어 있다. 한 사람의 총 친구 수를 구하려면 이 두 컬럼에 등장하는 본인의 ID를 모두 합산해야 한다.
2. Solution: 데이터 수직 통합 후 빈도 계산
UNION ALL을 사용해 두 컬럼의 ID를 하나의 열로 합친 뒤, 그룹화하여 개수를 세고 가장 높은 값을 추출한다.
3. Takeaway: 쿼리의 가독성과 효율성 (객관적 분석)
- UNION vs UNION ALL:
- UNION은 중복을 제거하지만, UNION ALL은 모든 데이터를 유지한다. 이 문제에서는 한 사람이 여러 명과 친구가 된 모든 '횟수'를 세어야 하므로, 중복을 제거하지 않는 UNION ALL을 사용하는 것이 논리적으로 정확하며 연산 속도도 더 빠르다.
- ORDER BY + LIMIT 1의 미학:
- 최댓값을 찾기 위해 서브쿼리 내에서 MAX()를 다시 호출하는 복잡한 방식 대신, 정렬 후 첫 번째 행만 가져오는 방식은 코드 가독성을 높이고 실행 계획을 단순화한다. 유진 님이 언급하신 "우아함"이 바로 이 지점에서 나타난다.
- 비즈니스 로직의 확장성:
- 만약 공동 1위가 있을 수 있는 상황이라면 RANK()나 DENSE_RANK() 윈도우 함수를 고려해볼 수 있으나, 이 문제처럼 "단 한 명의 1위"가 보장된 경우 LIMIT이 가장 효율적인 선택이다.
Table: RequestAccepted
+----------------+---------+
| Column Name | Type |
+----------------+---------+
| requester_id | int |
| accepter_id | int |
| accept_date | date |
+----------------+---------+
(requester_id, accepter_id) is the primary key (combination of columns with unique values) for this table.
This table contains the ID of the user who sent the request, the ID of the user who received the request, and the date when the request was accepted.
Write a solution to find the people who have the most friends and the most friends number.
The test cases are generated so that only one person has the most friends.
The result format is in the following example.
Example 1:
Input:
RequestAccepted table:
+--------------+-------------+-------------+
| requester_id | accepter_id | accept_date |
+--------------+-------------+-------------+
| 1 | 2 | 2016/06/03 |
| 1 | 3 | 2016/06/08 |
| 2 | 3 | 2016/06/08 |
| 3 | 4 | 2016/06/09 |
+--------------+-------------+-------------+
Output:
+----+-----+
| id | num |
+----+-----+
| 3 | 3 |
+----+-----+
Explanation:
The person with id 3 is a friend of people 1, 2, and 4, so he has three friends in total, which is the most number than any others.
데이터가 여러 컬럼에 흩어져 있을 때는 UNION ALL로 먼저 모으고,
1등을 찾을 때는 ORDER BY와 LIMIT의 콤비를 기억하세요. 복잡한 서브쿼리보다 정렬 한 번이 훨씬 빠르고 우아합니다.
1. 나의 정답 쿼리
# Write your MySQL query statement below
WITH total AS (
SELECT requester_id, accept_date
FROM RequestAccepted
UNION ALL
SELECT accepter_id, accept_date
FROM RequestAccepted
)
SELECT requester_id as id, COUNT(*) as num
FROM total
GROUP BY id
ORDER BY num DESC
LIMIT 1;