SQL
코테 준비 | Exchange Seats ( 홀수 짝수 자리바꾸기 - LAG,LEAD)
성장하는 쿠키의 로그 기록
2025. 1. 7. 10:40
☑️ 626. Exchange Seats
[문제]
- Write a solution to swap the seat id of every two consecutive students. If the number of students is odd, the id of the last student is not swapped.
- Return the result table ordered by id in ascending order.
- 아이디 짝수에서 홀수로 자리 바꾸기
[문제 풀이]
내 코드
WITH oby AS ( # 홀수 짝수 카운팅
SELECT id,student
,ROW_NUMBER() OVER (PARTITION BY id%2=1 ORDER BY id) AS rown
FROM SEAT
), idx AS(
SELECT student
FROM oby
ORDER BY rown,id desc
)
SELECT row_number () over () as id
,student
FROM idx
수정 코드1
SELECT id,
CASE
WHEN id % 2 = 0 THEN LAG(student) OVER(ORDER BY id)
ELSE COALESCE(LEAD(student) OVER(ORDER BY id), student)
END AS student
FROM Seat
수정 코드2
SELECT
ROW_NUMBER() OVER(ORDER BY IF(id%2= 0, id - 1, id + 1)) AS id
,student
FROM Seat
ORDER BY id
이슈 및 해결 과정
- 홀수 -> 짝수에서, 짝수 -> 홀수 인덱스로 학생 자리 바꾸는 문제
- 아이디어 : 홀수 /짝수별 각각 순서 매겨준 후 순서,ID로 정렬하여 문제 해결
- 1단계(oby with 문) : 홀수 -> 짝수 순으로 `ROW_NUMBER` 로 순서 매기기 (ex. id = 12345 ->11223)
- 2단계(idx with 문) : rown 오름차순,id 내림차 정렬해주고 student 아이디 출력
- `문제` rown 으로만 정렬해주면, 연속된 숫자 첫번째 순서에 student name별로 오는게 다양항( 앞/ 뒤 구분을 못함) → `id 내림차순` 정렬 조건 추가하여 해결
- 3단계 (아우터 쿼리) : id 인덱스 새롭게 정렬해줘야함. 만들어둔 테이블에서 순서 매겨서 해결 (row_number)
- 개선 쿼리1
- with 문 쓰지 않고 student 컬럼 lag/lead 윈도우 사용한 문제풀이법
- 아이디어 : id 고정시켜주고, 홀수일때를 먼저 가져오고, 짝수일때 미뤄줌 (조건문 & lag/lead 윈도우 함수로 접근)
- 짝수일때 student 한칸 가져오고, 홀수일때 student 한칸 미뤄줌 (when ~ then lag~)
- `문제` : 마지막 홀수에서 미뤄준 값 이 없어 null 로 출력 → coalesce (컬럼, student) 로 null 일때 원래 student 이름 그대로 출력
- 개선 쿼리2
- student 컬럼 사용하지 않고, id 컬럼 사용한 문제 풀이 법 (row_number)
- 아이디어 : 윈도우 order by 파라미터로 조건별(짝수/홀수) 아이디 숫자 밀고 당기기
- 짝수일때 id-1, 홀수일때 id+1
- id 로 최종 정렬
- 결론 ) 1번,2번 성능면으로 우수하고(시간 빠름) , 3번은 쿼리가 단순하고 가독성은 좋은데 성능이 좋지 못하다
- 1/2번 중에서도 가독성 좋은 2번 방식으로 연습
한줄 포인트
- 연속된 순서에서 행 바꿔주고, 이동할때 lag/lead 윈도우 함수 우선적으로 생각
- null 값 처리 coalesce 함수로 간단하게 변환 해줌