[해커랭크 SQL] Symmetric Pairs

hwan22·2022년 5월 4일
1

SQL 문제풀이

목록 보기
5/5

문제

Functions 테이블에서,
(x1, y1)과 (x2, y2) 두 쌍이 x1 = y2이고 y1 = x2 이면 대칭이다.
즉, 2개의 row가 나란히 세로로 있을때 X자 방향으로 값이 서로 같으면 대칭인 것.

이처럼 대칭인 row를 출력하는 쿼리를 짜되,
x1 <= y1이고 x, y 쌍을 x칼럼 기준으로 오름차순하는 쿼리를 작성해보자.


풀이

문제풀이 영상 보기 전 나의 쿼리

SELECT pre.x, pre.y
FROM Functions AS pre
             INNER JOIN Functions AS ne ON pre.x = ne.y
WHERE pre.x = ne.y AND pre.y = ne.x AND pre.x = pre.y
GROUP BY pre.x, pre.y, ne.x, ne.y
HAVING COUNT(*) > 1

UNION

SELECT pre.x, pre.y
FROM Functions AS pre
             INNER JOIN Functions AS ne ON pre.x = ne.y
WHERE pre.x = ne.y AND pre.y = ne.x AND pre.x < pre.y

ORDER BY x

풀이영상을 들어보니,
값이 같을 때는 굳이 INNER JOIN을 할 필요가 없었던거 같다.
(이 문제를 거의 1시간 반 넘게 잡고 있었던거 같다. 정답으로 처리됐긴 했지만 쿼리가 매우 맘에 안든다.)


백문이불여일타 영상풀이 쿼리

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

ex) (20, 20) 처럼 값이 같을 때의 대칭되는 row 값은 (20, 20)이므로 값이 같으면 (20, 20)인 row가 2개 필요함.

일단 이 문제의 핵심은 값이 같을 때와 다를 때의 대칭인 row들을 어떻게 나눠서 처리를 할 것이냐?
INNER JOIN으로 Self JOIN을 처음에 생각할 수 있냐 없냐 인듯하다.


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

즉, 대칭되는 다른 row 하나를 가지고 있는 row들만 출력하기 위해 INNER JOIN
ON f1.x = f2.y AND f1.y = f2.x 조건으로 찾을 수 있고,

f1.x != f1.y 조건을 줬을때, x = y 값이 다른 row들을 확인해볼 수 있다.
(x = y인 값들도 조인 시 나타나는데, 확인해보면 x = y인 row가 하나만 있으면 조인 결과도 하나만 나오고
(20, 20) row가 2개 있으면 조인 결과에서도 나란히 나타남.)

f1.xf1.yf2.x(조인으로 연결한 칼럼)f2.y(조인으로 연결한 칼럼)
10101010
20202020
20202020
138813
813138

이해를 위해 숫자는 임의로 하여 표로 만들어봄.

⛔️ UNION시 주의해야 할 점

UNION을 이용할 때,
ORDER BY는 꼭 맨 마지막 쿼리에다가 지정.
(세로로 결합된 전체 테이블에 대해서 ORDER BY가 실행됨. ORDER BY 칼럼명을 전체 테이블에 해당하는 칼럼명으로 해야함)

-> 이 문제에서는 합친 테이블에서 칼럼명이 x, y 이므로 ORDER BY절에는 x , y으로 정렬 가능.


💡 문제 풀면서 헷갈렸던 부분

  • 조인 할 때, ON f1.x = f2.y AND f1.y = f2.x 처럼 조건을 논리연산자로 이어서 여러개 쓸 수 있다는 점.

  • f1.x 처럼 f1 테이블에 있는 x칼럼은 출력시에 칼럼명이 f1.x가 아니라 그대로 x로 나타남.
    (즉, SELECT f1.x 으로 해도 테이블 이름은 빼고 원래 칼럼 이름인 x로 출력,
    평소에 SELECT문에 CASE문이나 함수를 쓰면 그대로 출력이 돼서 Alias 붙여줘야 하는줄 알았음..)

문제 링크

https://www.hackerrank.com/challenges/symmetric-pairs/problem
(해당 문제 저작권은 HackerRank에 있습니다.)

profile
기록의 공간

0개의 댓글