본문 바로가기
SQL/코딩테스트

[MySQL] 대칭 쌍 문제(Symmetric Pairs)

by Nanki 2024. 11. 6.

문제 : 

두 쌍 (X1 , Y1 ) 과 (X2 , Y2 ) 는 X1 = Y2 이고 X2 = Y1 인 경우  대칭 쌍 이라고 합니다 .
X 값에 따라 이러한 모든 대칭 쌍을 오름차순으로 출력하는 쿼리를 작성하세요 . X1 ≤ Y1 이 되도록 행을 나열하세요 .

 

X와 Y는 모두  Type은 Integer

 

샘플 입력 :

샘플 출력 :

20 20
20 21
22 23

 

문제 풀이 매크로

1. 문제 파악

순서 쌍에 대한 정의를 내린다.

순서 쌍을 이루는 경우는 3가지다. X1, Y1과 X2, Y2는 서로 다른 행이다. (보기쉽게 옆으로 붙여봤다)

1)

X1 Y1 X2 Y2
20 20 20 20


2)

X1 Y1 X2 Y2
30 20 20 30


3)

X1 Y1 X2 Y2
20 30 30 20

 

이때 1)을 따로 풀고, 2)와3)을 같이 풀어서 UNION을 해주겠다.

 

2. 1-1)번 풀이 : X와 Y의 숫자가 같으면서, 동일한 행이 2번 이상 나와야 한다.

   WHERE X=Y / GROUP BY X, Y HAVING COUNT(*) >=2

3. 2), 3)번 풀이 :

- X=Y 그리고 Y=X인 행들을 뽑아야 한다. 

Self JOIN이용 / INNER JOIN ON X=Y AND Y=X

- 문제의 조건처럼 X는 Y보다 작아야 된다.

WHERE X < Y

- 문제의 조건처럼  X를 정렬해야 한다.

ORDER BY X

 

완성 코드

SELECT X, Y
FROM Functions
WHERE X = Y
GROUP BY X, Y
HAVING COUNT(*) >= 2

UNION

SELECT f1.X, f1.Y
FROM functions AS f1
    INNER JOIN functions AS f2
    ON f1.X = f2.Y AND f1.Y = f2.X
WHERE f1.X < f1.Y
ORDER BY X
;

 

 

직접 풀었던 코드

SELECT X, Y
FROM Functions
WHERE X = Y
GROUP BY X, Y
HAVING COUNT(*) >= 2

UNION

SELECT DISTINCT origin_X AS X, origin_Y AS Y
FROM (
        SELECT 
            A.X AS origin_X
            ,A.Y AS origin_Y
            ,B.X AS add_X
            ,B.Y AS add_Y
            , CASE WHEN ((A.X=B.Y) AND (B.X=A.Y)) AND (A.X < B.X )THEN 1 ELSE 0 END AS flag

        FROM Functions AS A
            LEFT JOIN Functions AS B
            ON A.Y=B.X
    ) AS C
WHERE (flag = 1) 
ORDER BY X
;

 

문제 풀이 매크로 단계에서 2단계에서 직접 푼 쿼리와 차이점은 아래와 같다.

 

X=Y 그리고 Y=X인 행들을 뽑을 때 접근 방법 

완성 코드 : Self INNER JOIN 으로 X=Y 그리고 Y=X인 조건을 걸어 뽑았다. 

직접 작성한 코드 :

1) X=Y 그리고 Y=X을 무언가를 하기 위해 옆으로 붙여야 된다고 생각하고 LEFT JOIN을하였다.

2) CASE WHEN 으로 X=Y 그리고 Y=X인 행들을 값이 1이고, 아닌 행은 0이면서, 

또 문제 조건이었던 A.X < B.X인  Flag 변수를 만들었다. 

3) 만들어논 Flag 변수를 사용하기 위해 SUB 쿼리로 넣고 WHERE문으로 Flag 변수를 1인 행들만 출력했다.

 

배운 점 :

 - 문제 접근시 패턴을 나누어 각각 접근해보도록 하자. ( 1-(1 와 1-(2, 1-(3를 각각 쿼리 작성했던 것 처럼)

 - INNER JOIN을 Self 쿼리에서 사용하면 다른 행끼리 비교를 통해 원하는 행을 바로 뽑을 수 있다. (굳이 FlAG변수 + sub쿼리를 안만들어도 된다.)

 - UNION 작성시 ORDER BY는 맨 마지막 쿼리 하단에 1번만 들어가야 한다.

 

 

 

문제 출처 : https://www.hackerrank.com/challenges/symmetric-pairs/problem