본문 바로가기

학습/SQL

[solvesql] SQL 풀어보기 - 세 명이 서로 친구인 관계 찾기

✔️ 문제

소셜 네트워크 분석에서는 세 명의 사용자가 서로 친구 관계인 경우를 중요하게 생각합니다. 

주어진 데이터를 활용해 ID가 3820인 사용자를 포함해 세 명의 사용자가 친구 관계인 경우를 모두 출력하는 쿼리를 작성해주세요. 

중복된 세 친구 관계를 제외하기 위해 user_a_id < user_b_id < user_c_id를 만족하는 경우만 출력되어야 합니다.

 

✔️ LEVEL 4

 

📌 주요 요구사항

  • user_a_id와 user_b_id가 친구 관계를 나타냄.
  • 친구 관계는 단방향으로만 저장되어 있으므로, 양방향 관계를 직접 만들어야 함.
  • 세 명의 사용자가 서로 친구 관계를 맺고 있는 경우를 찾아야 함.
  • 중복된 조합을 방지하기 위해 user_a_id < user_b_id < user_c_id 조건을 적용해야 함.
  • 찾은 친구 관계 중 ID가 3820인 사용자가 포함된 경우만 출력해야 함.
with friend as (select * from edges
        union ALL
	select user_b_id, user_a_id from edges
),
friend3 as (
  select f1.user_a_id,f1.user_b_id, f2.user_b_id user_c_id
  from friend f1 join friend f2 on f1.user_b_id = f2.user_a_id 
) 

select *
from friend3
where (user_a_id,user_c_id) in (
				select user_a_id,user_b_id from friend)
and user_a_id < user_b_id and user_b_id < user_c_id
and (user_a_id = 3820 or user_b_id = 3820 or user_c_id = 3820)

✍ 코드 해석

1. WITH friend AS (...) 서브쿼리

  • UNION ALL을 사용하여 양방향 친구 관계로 변환
  • 예를 들어, (1, 59)가 존재하면 (59, 1)도 포함되도록 변환

2. friend3 서브쿼리

  • friend 테이블을 셀프조인 활용하여  두 명의 친구 관계를 조인하여 세 명의 친구 관계를 만듦
  • f1.user_a_id, f1.user_b_id, f2.user_b_id를 가져와 user_c_id로 설정

3. 최종 필터링 조건 적용

  • 세 번째 사용자(user_c_id)도 첫 번째 사용자(user_a_id)와 친구인지 확인 → IN 조건 사용하여 friend 테이블에서 찾기
  • 중복된 조합을 방지 → user_a_id < user_b_id < user_c_id 조건 적용
  • ID가 3820인 사용자 포함 → WHERE 절에서 OR 조건으로 필터링

 

📌 실행 결과

  • 55개의 데이터가 출력됨
  • 3820번 사용자가 포함된 친구 관계만 출력
  • 각 그룹은 중복되지 않으며, 세 명의 친구가 서로 연결된 상태

 

 

✔마무리

하나하나 조인해가며 출력해가며 코드가 복잡해지게 풀었는데

어떤분이 너무 가볍게 풀어놓은 풀이를 보고 아차차 하게 되었다.

 

나도 sql 문장이 가볍고 가독성 높아지는 그날까지 ㅠㅠㅠㅠ

화이팅이다!