Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | |
7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | 30 |
Tags
- SQLite
- mssql 대용량 데이터 insert
- solvesql
- c#
- 윈도우함수
- Java
- MS-SQL
- jdbc
- mssql 대용량 데이터
- mssql insert
- SQL Server
- 테이블용량조회
- 어노테이션
- annotation
- MSSQL INDEX
- sql insert
- mssql bulk insert
- jdbc bulk insert
- 자바
- SQL
- lag
- sql index
- jtds
- MSSQL 인덱스
- 포인터
- C++
- 자바 어노테이션
- MSSQL
- select count
Archives
- Today
- Total
Basic Byte Bites
[SolveSQL/Advent of SQL 2024] 세 명이 서로 친구인 관계 찾기 본문
문제:
https://solvesql.com/problems/friend-group-of-3/
처음엔 간단(?)해 보였지만 하면 할수록 점점 이상한 결과들이 나오기 시작했다..
셀프 조인을 2~3번씩 걸면서 조건을 이렇게 저렇게 주고 해봤는데 원하는 결과가 나오지않아서 결국 야매스러운 방법으로 해결했다..

1. Edges 테이블의 USER_A_ID 혹은 USER_B_ID가 3820인 행찾기
2. 3820의 친구목록을 하나의 컬럼으로 묶어주기
WITH UserFriends AS (
SELECT
CASE WHEN User_A_Id = 3820 THEN USER_B_ID
ELSE User_A_Id
END as Friend
FROM Edges
WHERE 3820 IN (user_a_id, user_b_id)
)
3. [3820의 친구목록] 중 Edges테이블의 [user_a_id, user_b_id] 두 컬럼 모두에 해당하는 행을 찾은 후 작은수, 큰수로 정렬하여 중복제거 [1, 2], [2, 1]과 같은 조합이 있을 수 있으므로..
ex) 3820의 친구목록이 1,2,3,4 라면 Edges 테이블의 [user_a_id, user_b_id] 조합이 [1,2,3,4]에서 조합되는 녀석
FriendPairs AS (
SELECT DISTINCT
CASE
WHEN E.user_a_id < E.user_b_id THEN E.user_a_id
ELSE E.user_b_id
END as user_a_id,
CASE
WHEN E.user_a_id < E.user_b_id THEN E.user_b_id
ELSE E.user_a_id
END as user_b_id
FROM Edges E
INNER JOIN UserFriends UF1 ON E.user_a_id = UF1.Friend
INNER JOIN UserFriends UF2 ON E.user_b_id = UF2.Friend
)
풀고나서 알았는데 Edges컬럼의 user_a_id < user_b_id는 항상 참이다. 즉 위의 CASE구문없이 user_a_id, user_b_id만 조회 했어도 됐음
중간결과
이제 위 user_a_id, user_b_id 사이에 A < B < C 순으로 3820을 끼워넣으면 된다.
어떻게할까 고민좀 하긴 했는데.. 그냥 무식하게 CASE로 때려박았다..
4. 최종결과
WITH UserFriends AS (
-- 3820 유저의 모든 친구
SELECT
CASE WHEN User_A_Id = 3820 THEN USER_B_ID
ELSE User_A_Id
END as Friend
FROM Edges
WHERE
3820 IN (user_a_id, user_b_id)
),
FriendPairs AS (
-- 3820 유저의 친구들 쌍
SELECT DISTINCT
CASE
WHEN E.user_a_id < E.user_b_id THEN E.user_a_id
ELSE E.user_b_id
END as user_a_id,
CASE
WHEN E.user_a_id < E.user_b_id THEN E.user_b_id
ELSE E.user_a_id
END as user_b_id
FROM Edges E
INNER JOIN UserFriends UF1 ON E.user_a_id = UF1.Friend
INNER JOIN UserFriends UF2 ON E.user_b_id = UF2.Friend
)
SELECT
CASE WHEN USER_A_ID < 3820 AND USER_B_ID < 3820 THEN USER_A_ID -- [3820]이 가장 큰 경우
WHEN USER_A_ID < 3820 THEN USER_A_ID -- [3820]이 중간인 경우
ELSE 3820 -- [3820]이 가장 작은 경우
END as user_a_id,
CASE WHEN USER_A_ID < 3820 AND USER_B_ID < 3820 THEN USER_B_ID
WHEN USER_A_ID < 3820 THEN 3820
ELSE USER_A_ID
END as user_b_id,
CASE WHEN USER_A_ID < 3820 AND USER_B_ID < 3820 THEN 3820
WHEN USER_A_ID < 3820 THEN USER_B_ID
ELSE USER_B_ID
END as user_c_id
FROM
FriendPairs
참으로 무식한 결과다.. ㅎㅎ
하지만 통과^^
'DataBase' 카테고리의 다른 글
[SolveSQL/Advent of SQL 2024] 스테디셀러 작가 찾기 (1) | 2024.12.27 |
---|