본문 바로가기
MYSQL/HakerRank_Medium

Symmetric Pairs 과 Self_Join

by 수스리 2025. 4. 22.

You are given a table, Functions, containing two columns: and Y.

Two pairs (X1, Y1) and (X2, Y2) are said to be symmetric pairs if X1 = Y2 and X2 = Y1.

Write a query to output all such symmetric pairs in ascending order by the value of X. List the rows such that X1 ≤ Y1.

두 쌍 *(X1, Y1)*과 *(X2, Y2)*는 X1 = Y2이고 X2 = Y1일 때 대칭 쌍이라고 합니다.

이러한 모든 대칭 쌍을 X 값의 오름차순으로 출력하는 쿼리를 작성하세요. X1 ≤ Y1인 행들만 나열하세요.

SELECT DISTINCT F1.X, F1.Y
FROM Functions F1
JOIN Functions F2 ON F1.X = F2.Y AND F1.Y = F2.X
WHERE F1.X <= F1.Y AND
    (F1.X != F1.Y OR (SELECT COUNT(*) FROM Functions WHERE X = F1.X AND Y = F1.Y) > 1)
ORDER BY F1.X ASC;

아래가 정답 코드다. 이건 조인 보다 WHERE 절이 까다롭다. 아래는 내 초기코드다.

SELECT *
FROM Functions F1
JOIN Functions F2 ON F1.X = F2.Y AND F1.Y = F2.X
WHERE F1.X <= F1.Y
ORDER BY F1.X ASC;

이러면 어느정도는 맞는데 문제가 생긴다. 가령 (20, 20) 좌표가 있다 치자. 위 코드는 Self JOIN이다. Self Join을 하면 자기 자신도 참조한다. 그럼 (20, 20)이 하나만 있어도 대칭쌍으로 된다. 컴퓨터 입장에서 (20, 20)을 두번 읽었으니. 이 경우를 처리할 조건이 필요하다.

  1. X ≠ Y인 경우: 그대로 진행
  2. X = Y인 경우: 같은 쌍이 2개 이상 있어야 함

그래서 위와 같은 (F1.X != F1.Y OR (SELECT COUNT(*) FROM Functions WHERE X = F1.X AND Y = F1.Y) > 1) 서브쿼리가 나왔다.

 

정확합니다!

OR 조건 때문에 두 가지 경우가 처리됩니다:

  1. F1.X != F1.Y: X와 Y가 다른 경우 (예: (3, 24), (24, 3))
  2. (SELECT COUNT(*) FROM Functions WHERE X=F1.X AND Y=F1.Y) > 1: 이 조건은 OR의 첫 번째 조건이 false일 때만 실행됩니다.

즉, F1.X != F1.Y가 false라는 것은 F1.X = F1.Y라는 뜻이므로, 이 서브쿼리는 X=Y인 경우에만 실행됩니다.

논리적으로:

  • X ≠ Y인 경우: 첫 번째 조건(F1.X != F1.Y)이 true이므로 바로 통과
  • X = Y인 경우: 첫 번째 조건이 false이므로 두 번째 조건(COUNT > 1)을 확인

따라서 (20, 20)같은 경우는 테이블에 2개 이상 있어야만 결과에 포함됩니다.

<2025년 5월 6일 복습>

SELECT x, y
FROM FUNCTIONS
WHERE x = y
GROUP BY x, y
HAVING COUNT(*) = 2 
UNION
SELECT F1.x, F1.y
FROM FUNCTIONS F1
JOIN FUNCTIONS F2 ON F1.X = F2.Y AND F1.Y = F2.X
WHERE F1.y > F1.x
ORDER BY x

이번은 이전 쿼리와 조금 다르다. 가장 달라진점은 UNION을 써싸는 점이다. 문제에서 요구조건을 만족하는 경우의 수는 크게 두가지인데 X와 Y가 같고 그 쌍이 두개 일 때, 그리고 일반적인 경우에서 Y가 X보다 클 때이다.

처음 문제를 풀 때 한 쿼리 안에서 해결하려고 했는데 그러는 것 보다 UNION을 써서 쿼리를 두개 쓰는 게 더 편해 보인다. 이런경우에는 쪼개서 생각해보자 

'MYSQL > HakerRank_Medium' 카테고리의 다른 글

Print Prime Numbers  (0) 2025.04.24
Placements 과 Join  (0) 2025.04.22
SQL Project Planning과 Islands and Gaps 패턴  (0) 2025.04.21
Contest Leaderboard  (0) 2025.04.21
Challenges 와 WITH 절  (0) 2025.04.18