문제 :
두 쌍 (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
'SQL > 코딩테스트' 카테고리의 다른 글
[MySQL] SUBSTR/REGEXP/LEFT/RIGHT 문자열 다루기 (1) | 2024.11.08 |
---|---|
[MySQL] INNER JOIN과 LEFT JOIN 쓰임 / COUNT(DISTINCT) (0) | 2024.11.07 |
[MySQL] Self join을 활용한 코딩테스트 주의사항 (0) | 2024.11.05 |
[MySQL] Self Join (0) | 2024.11.05 |
[MySQL] 그룹변수가 2개로 피벗테이블 구성 (0) | 2024.11.05 |