본문 바로가기
문제풀이/SQL(My sql)

[문제풀이] Hacker Rank - Symmetric Pairs

by kime2 2024. 6. 19.
출처
 

Symmetric Pairs | HackerRank

Write a query to output all symmetric pairs in ascending order by the value of X.

www.hackerrank.com

 

문제

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.

문제에 대한 해석

X와 Y가 짝이 되기 위해서는 다음의 조건이 필요하다

X1 = Y2 and X2 = Y1.  

이렇게 x와 y가 동일해야 한다(반대로도)

그러나 x1과 x2는 다음행일 필요는 없다 > 쿼리에서 찾는 것

 

이때 x가 y보다 크거나 작을 경우의 x1과 y1을 조회하라 ( List the rows such that X1 ≤ Y1.)

풀이(MYSQL)

-- 오답
select a.x,a.y
from Functions a
join (select lead(x,1)over() as x2,lead(y,1)over() as y2
    from Functions )b
on a.x =b.y2 and a.y =b.x2
where a.x<=a.y
order by a.x

 

해석

1행의 x,y다음행의 x,y를 비교해서  X1 = Y2 and X2 = Y1인 경우 인너조인하여

x가 y보다 큰 경우 줄력하라

 

오류

x1과 x2는 행렬순이 아니다

예시 답안을 보면 20과 21이 있다

하단 테이블을 보면 20,21은 서로 붙어있지 않다

 

-- 2% 부족한 오답
with tmp as (
select x,y,row_number()over() as n
from Functions)
select a.x, a.y, a.n ,b.x, b.y,b.n
from tmp a
join tmp b
on a.x = b.y and a.y =b.x
and a.n <> b.n

x1과 y1이 같고 x2와 y2가 같은데

row_number을 통해 서로 같은 데이터는 아니다

 

내쿼리 정답쿼리

13,13이 오답에는 2번 들어가 있다

row_number을 보면 다른 행의 데이터 인데 (X1, Y1) , (X2, Y2) = (30,30),(30,30) 무엇이 문제일까?

 

다시 샘플 답안을 보면

(X1, Y1) , (X2, Y2) = (20,20),(20,20)인데 20,20으로 1번만 들어가 있다

 문제에서 정확하게 명시되것인지는 모르겠지만 x1,y1만 출력되야 하는 것 같다

그렇다면 (X1, Y1)을 기준으로 그룹핑하면 될라나? > 정답!

 

-- 정답
with tmp as (
select x,y,row_number()over() as n
from Functions)
select a.x, a.y
from tmp a
join tmp b
on a.x = b.y and a.y =b.x
and a.n <> b.n
where a.x <= a.y
group by a.x, a.y
order by a.x

 

작동순서

💡SQL 실행 순서는 From -> Where -> Group by -> Having -> Select -> Order by ->결과반환

 

  1. WITH 절: Functions 테이블에서 x,y, 그리고 각 행의 row_number을 붙여서 출력해서 tmp임시 테이블에 저장
  2. FROM절 : tmp테이블과 tmp테이블을 각각 a,b라고 별칭하고 a의 x와 b의 y가 같고 a의y와 b의x가 같은 경우와 a의숫자(row_number)와 b의 숫자 (row_number)가 다를 경우 조인하라 > 같은x,y끼리 조인하는 것을 방지
  3. WHERE 절:  a.x 가a.y보다 크거나 작을 경우 필터링 하여
  4. GROUP BY 절:  a.x 와a.y를 그룹핑하여
  5. SELECT 절: (그룹핑된)a.x 와a.y 조회
  6. ORDER BY 절: a.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 
의미 :  x와y가 같을때 1개만 출력
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
의미 : functions의 x와 functions의 y가 같고 그 반대로도 같을때 이너조인하여 
x가 y보다 작은 경우 필터링