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 함수로 간단하게 변환 해줌