본문 바로가기
DataBase

[HackerRank] Symmetric Paris

by 작심평생 2020. 6. 10.

새로운 기술이나 java, spring에 대한 지식도 중요하지만
그만큼 많이 쓰는 DB에 대한 지식도 공부할 필요성을 느끼게 되었다.

아직 프로시저나 function 등 어려운 부분이 많지만.. 1년 차를 넘어갔으니
조금씩 공부하면서 익숙해져야겠다!

그러면서 쿼리문 학습을 위해 ‘해커 랭크’에서 SQL 문제를 꾸준히(.. 제발) 풀려고 한다.
각설하고, 이번에 생각하기 좀 힘들고 착각도 많이 한 Self Join을 활용한 문제 해결법이다.

고민하다가 결국 Discussion에 다른 사용자가 작성한 쿼리(아래 해결쿼리가 그것이다..)를 보긴 했지만
생각하는 시간이 되었다.

해당 문제 링크
https://www.hackerrank.com/challenges/symmetric-pairs/problem?h_r=next-challenge&h_v=zen&h_r=next-challenge&h_v=zen

 


 

 

해결 쿼리

1
2
3
4
5
6
7
SELECT f1.X, f1.Y FROM Functions f1
INNER JOIN Functions f2 ON f1.X=f2.Y AND f1.Y=f2.X
 
GROUP BY f1.X, f1.Y
HAVING COUNT(f1.X)>1 or f1.X<f1.Y
 
ORDER BY f1.X;


문제 해결 조건으로는 
    1. X1 = Y2 and X2 = Y1
    2. X < Y
    3. X 기준 오름차순 정렬

2번의 경우는 Discussions을 보고 알았다. 문제 수정이 좀 필요한 거 같다.

헷갈렸던 부분은 1번이다.
내가 판단한 내용은 다음과 같다.

    X1 = 현재 Row의 X 컬럼의 값
    X2 = 다음 Row의 X 컬럼의 값

때문에 현재 Row와 다음 Row의 값만 비교하면 되겠다 싶어 LEAD 함수를 사용했지만
그게 아니었다. 

현재 Row의 X값이 Y컬럼의 값들 중에 있고
현재 Row의 Y값이 X컬럼의 값들 중에 있는지를 확인해야 하는 것이었다.

위의 샘플 테이블 에서 (20, 21) 데이터를 보면

X의 20이라는 데이터가 Y컬럼 값들 중에 있고
Y의 21이라는 데이터가 X컬럼 값들 중에 있다.
그리고 20 < 21 이기 때문에 문제에 맞는 데이터라는 것이다.

그러면 이걸 어떻게 접근해야 할까?
Self Join을 이용하여 값이 있는지 여부를 확인할 수 있게 된다.

1
2
3
4
SELECT 
    f1.X, f1.Y, f2.X, f2.Y
FROM Functions f1
LEFT OUTER JOIN Functions f2 ON f1.X=f2.Y AND f1.Y=f2.X


이렇게 JOIN을 걸면 ON 절 조건에 의해 다음과 같은 결과를 확인할 수 있다.

(20, 20, 20, 20)
(20, 20, 20, 20)
(20, 21, 21, 20)
(23, 22, 22, 23)
(22, 23, 23, 22)
(2, 12, NULL, NULL) ——> 문제의 1번 조건이 없는 경우 이런 값이 나오게 된다. (이건 본인이 임의로 만든 값)

마지막 NULL 값이 있는 데이터의 경우, 문제의 1번 조건에 해당하지 않기 때문에
제외시켜야 한다. 따라서 LEFT OUTER에서 INNER JOIN으로 바꿔야 한다.

또한 GROUP BY 후 HAVING 절에 아래 조건을 작성한다.

1
HAVING COUNT(f1.X) > 1 or f1.X < f1.Y
cs


COUNT의 경우 같은 Row값이 있는 경우를 위해서다.
이는 (20, 20) , (20,20) 같이 중복된 값이 있는 경우를 찾는 것이다.

두 번째 f1.X<f1.Y 의 경우는
이미 1번 조건은 만족했고, 중복된 값도 확인했기 때문에 2번 조건을 위해서 필요한 것이다.

마지막으로 X컬럼 순서로 오름차순 정렬하면 끝.

댓글