Advented of SQL 2024 : 세 명이 서로 친구인 관계 찾기 (DAY 24)

Hyeon·2024년 12월 25일

SQL 문제 풀이

목록 보기
61/61

문제 탐구

주어진 데이터를 활용해 ID가 3820인 사용자를 포함해 세 명의 사용자가 친구 관계인 경우를 모두 출력하는 쿼리를 작성해주세요.
중복된 세 친구 관계를 제외하기 위해 user_a_id < user_b_id < user_c_id를 만족하는 경우만 출력되어야 합니다.

✔️출력컬럼
user_a_id: 친구 관계인 사용자 ID (A)
user_b_id: 친구 관계인 사용자 ID (B)
user_c_id: 친구 관계인 사용자 ID (C)

코드

1번째 시도

with new_t as (select  user_a_id as user_b_id,user_b_id as user_c_id from edges),
cte_1 as (select distinct user_a_id ,e.user_b_id , user_c_id from edges e join new_t t on e.user_b_id = t.user_b_id where user_a_id < e.user_b_id and e.user_b_id < user_c_id)

select * from cte_1 where user_a_id in (3820) or  user_b_id in (3820) or  user_c_id in (3820);

총 81개 행.. 정답 레코드 개수는 55개

2번째 시도

with cte_1 as (SELECT *
FROM edges
WHERE 3820 in (user_a_id, user_b_id)),
cte_2 as (SELECT user_a_id as user_b_id, user_b_id as user_c_id 
FROM edges 
WHERE 3820 in (user_a_id, user_b_id))
select user_a_id,c1.user_b_id, user_c_id from cte_1 c1 join cte_2 c2 on c1.user_b_id = c2.user_b_id;

3820 조건을 먼저 넣고 user값을 출력해야하나 싶어 다음과 같이 구했지만 총 32개의 행이 나옴

3번째 시도 : 정답 코드

🚩이때 문제점을 깨달음!
"user_a_id 와 user_c_id 도 친구관계여야하는구나..!"

💡내가 여태까지 구했던건 user_a_id 와 user_b_id가 친구관계, user_b_id와 user_c_id가 친구관계였던 case 고 , 조건 1개를 더 추가해서 3명 모두가
친구관계인것을 출력해야한다

with cte_1 as (
  select * 
  from edges 
  ),
cte_2 as (
  select user_b_id as user_c_id ,user_a_id as user_b_id
  from edges   
  ),

cte_3 as (select distinct user_a_id,user_b_id,user_c_id FROM
(select * from cte_1 left join cte_2 on cte_1.user_b_id = cte_2.user_b_id
 
UNION
select * from cte_1 right join cte_2 on cte_1.user_b_id = cte_2.user_b_id

where user_a_id is not null and user_c_id is not null and cte_1.user_b_id is not null) t
where (3820) in (user_a_id,user_b_id, user_c_id) and user_a_id <user_b_id and user_b_id < user_c_id)

select c.user_a_id, c.user_b_id, user_c_id from cte_3 c join edges e on c.user_a_id = e.user_a_id and e.user_b_id = c.user_c_id;

코드 간소화 : 정답 코드

코드가 너무 길어서 짧게 줄여보았음

with cte_1 as (select user_a_id, e.user_b_id, user_c_id 
from edges e 
join 
(select user_b_id as user_c_id , user_a_id as user_b_id 
from edges) e2
on e.user_b_id = e2.user_b_id 
where (3820) in (user_a_id ,e.user_b_id, user_c_id))

-- user_a_id와 user_b_id & user_b_id 와 user_c_id가 서로 친구관계 확인
-- user_a_id와 user_c_id가 친구관계인것도 확인해야함!!!
select c.user_a_id ,c.user_b_id, user_c_id from edges e join cte_1 c 
on e.user_a_id = c.user_a_id and e.user_b_id = c.user_c_id 

주의할 점!

💡3명의 사용자 모두가 친구관계여야하기 때문에
1.user_a_id & user_b_id
2.user_b_id & user_c_id
3.user_a_id & user_c_id
3개 조건이 필요하다.

💡+ user_a_id <user_b_id < user_c_id 조건이 필수적
BUT 해당 edges테이블에는 애초에 모든 레코드가 user_a_id < user_b_id 로 되어있기 때문에 별도로
where user_a_id < user_b_id and user_b_id < user_c_id
조건을 추가하지 않았다.

오예 (●'◡'●) 25일에 모든 문제를 다 끝내버렸다
안풀릴때마다 심란했지만 너무 재밌었던 sql 챌린지
또 풀어주셨으면 좋겠다..(❁´◡`❁)

0개의 댓글