반응형
https://solvesql.com/problems/friendship-between-early-users/
https://solvesql.com/problems/friendship-between-early-users/
solvesql.com
Facebook 소셜 네트워크 데이터베이스에는 사용자의 정보와 사용자 사이의 친구 관계가 저장되어 있습니다.
edges 테이블의 각 행은 두 사용자(user_a_id, user_b_id)가 서로 친구 관계라는 의미입니다.
이 데이터베이스에서 사용자 ID는 auto increment 정수로 생성되기 때문에, ID가 낮을수록 더 일찍 가입한 사용자라고 볼 수 있습니다.
따라서 친구 관계인 두 사용자 ID의 합(user_a_id + user_b_id)이 작을수록 더 초창기에 형성된 친구 관계일 가능성이 높다고 추측할 수 있습니다.
🎯 문제 정리
테이블: edges
주요 컬럼
- user_a_id : 친구 관계 사용자 A의 ID
- user_b_id : 친구 관계 사용자 B의 ID
찾고 싶은 값
- 전체 친구 관계 중에서
두 사용자 ID의 합(id_sum)이 “상위 0.1%”에 해당하는 모든 친구 관계
출력 컬럼
- user_a_id
- user_b_id
- id_sum (= user_a_id + user_b_id)
🎯 문제 해결 흐름
친구 관계 한 줄을 기준으로, 우리는 다음을 계산해야 합니다.
- 각 친구 관계의 id_sum 계산 (id_sum = user_a_id + user_b_id)
- id_sum이 작은 순서대로 정렬해서 “초기일수록 앞쪽”에 오게 한다.
- 그 정렬 결과에서 각 관계의 순위(rn) 를 만든다. (가장 초기 관계가 1등, 다음이 2등 …)
- 전체 친구 관계 수(total_cnt)를 구한다.
- 문제에서 정의한 “상위 %”는 아래와 같다.
- 상위 % = 순위 / 전체 관계 수
- 따라서 “초기 0.1%”는 rn / total_cnt <= 0.001
- 이 조건을 만족하는 친구 관계만 출력하면 된다.
🎯쿼리
WITH ranked AS (
SELECT
user_a_id,
user_b_id,
(user_a_id + user_b_id) AS id_sum,
ROW_NUMBER() OVER (ORDER BY (user_a_id + user_b_id) ASC) AS rn,
COUNT(*) OVER () AS total_cnt
FROM edges
)
SELECT
user_a_id,
user_b_id,
id_sum
FROM ranked
WHERE rn / total_cnt <= 0.001
ORDER BY id_sum ASC, user_a_id, user_b_id
🎯 핵심 문법 설명
1) ROW_NUMBER() — 정렬된 결과에 “번호표(순위)” 붙이기
ROW_NUMBER() OVER (ORDER BY id_sum ASC)
- ORDER BY id_sum ASC 기준으로 줄 세운 뒤
- 각 행에 1, 2, 3… 번호를 붙입니다.
- 즉, rn은 id_sum이 작은 순서 기준 몇 번째인지(순위)를 의미합니다.
이 문제에서는 “초기 친구 관계”를 찾으므로
id_sum이 작은 관계가 앞 순위가 되도록 ASC를 사용합니다.
2) COUNT(*) OVER() — 전체 행 개수를 모든 행에 붙이기
COUNT(*) OVER ()
- edges 테이블 전체 행 수(=전체 친구 관계 수)를
- 각 행마다 동일하게 붙입니다.
- 즉, total_cnt는 “전체 관계 수”입니다.
3) “상위 0.1%” 조건 구현
문제에서 정의한 상위 %:
상위 % = 순위 / 전체 관계 수
이를 그대로 SQL로 쓰면:
WHERE rn / total_cnt <= 0.001
- 0.001 = 0.1%
- “초기 0.1%”에 해당하는 관계만 필터링 됩니다.
이 문제는 단순한 SELECT가 아니라 윈도우 함수의 진짜 쓰임새, 순위 기반 퍼센트 필터링 등을 한 번에 보여주는 좋은 문제 입니다.
특히 ROW_NUMBER + COUNT(*) OVER 조합은 익혀둡시다!!!!
반응형
'SQL' 카테고리의 다른 글
| [SQL/solvesql LV2] 이틀 연속 미세먼지가 나빠진 날 (0) | 2025.12.07 |
|---|---|
| [SQL/solvesql LV4] 세 명이 서로 친구인 관계 찾기 (1) | 2025.03.20 |
| [SQL/프로그래머스 LV3] 멀티 플랫폼 게임 찾기 (0) | 2025.02.05 |
| [SQL/프로그래머스 LV3] 대여 횟수가 많은 자동차들의 월별 대여 횟수 구하기 (4) | 2025.01.17 |
| [SQL/프로그래머스 LV.3] 헤비 유저가 소유한 장소 (3) | 2025.01.16 |