출처
문제
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 ->결과반환
- WITH 절: Functions 테이블에서 x,y, 그리고 각 행의 row_number을 붙여서 출력해서 tmp임시 테이블에 저장
- FROM절 : tmp테이블과 tmp테이블을 각각 a,b라고 별칭하고 a의 x와 b의 y가 같고 a의y와 b의x가 같은 경우와 a의숫자(row_number)와 b의 숫자 (row_number)가 다를 경우 조인하라 > 같은x,y끼리 조인하는 것을 방지
- WHERE 절: a.x 가a.y보다 크거나 작을 경우 필터링 하여
- GROUP BY 절: a.x 와a.y를 그룹핑하여
- SELECT 절: (그룹핑된)a.x 와a.y 조회
- 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보다 작은 경우 필터링 |
'문제풀이 > SQL(My sql)' 카테고리의 다른 글
[문제풀이] 프로그래머스 - 연간 평가점수에 해당하는 평가 등급 (0) | 2024.06.24 |
---|---|
[문제풀이] Hacker Rank - Draw The Triangle 1, 2 (0) | 2024.06.20 |
[문제풀이] Hacker Rank - Placements (1) | 2024.06.18 |
[문제풀이] Hacker Rank - Challenges (1) | 2024.06.18 |
[문제풀이] Hacker Rank - SQL Project Planning (0) | 2024.06.14 |