626. Exchange Seats : leetcode

오유찬·2026년 1월 12일

SQL

목록 보기
42/71

1,2/ 3,4 / 5,6 이런 식으로 레코드들을 묶어서 그룹으로 만들려면?

  • ROW_NUMBER()는 써야 될 것 같고
  • even, odd니까 2로 나누면 될텐데 소수점을 올림해서 사용
    CEIL( (ROW_NUMBER() OVER(ORDER BY id)) / 2 )

같은 그룹 내에서 swap을 하려면?

  • 그룹 내 개수가 2개일 때 swap 가능
  • 그룹 내에서 순서를 어떻게 바꾸면서 값도 압축시키지 않을까
-- swap?
WITH cte as (SELECT  id, student,
            CEIL( (ROW_NUMBER() OVER(ORDER BY id)) /  2) as group_num,
            ROW_NUMBER() OVER(ORDER BY id) as num
            FROM    Seat)

SELECT  *
FROM    cte
ORDER BY
        group_num, id DESC

여기에서 ROW_NUMBER() OVER(ORDER BY id) as num으로 한 이유가
group_num, id로 정렬한 거랑은 별개로 1,2,3,4,5로 유지되는 컬럼을 갖기 위해서였는데 위와 같이 사용하면 id 옆에 같은 값으로 num이 새겨지는 것 밖에 안 된다.

idstudentgroup_numnum
2Doris12
1Abbot11
4Green24
3Emerson23
5Jeames35

이렇게 나온다.

-- swap?
WITH cte as (SELECT  id, student,
            CEIL( (ROW_NUMBER() OVER(ORDER BY id)) /  2) as group_num

            FROM    Seat)

SELECT  id, student, group_num,
        ROW_NUMBER() OVER(ORDER BY group_num, id DESC) as num
FROM    cte
ORDER BY 
        group_num, id DESC

window function을 사용할 때, 새로 정렬한 순서에 맞게 다시 번호를 매기고 싶다면 window function 내 정렬과 테이블의 정렬을 같도록 해야 한다.

idstudentgroup_numnum
2Doris11
1Abbot12
4Green23
3Emerson24
5Jeames35

num 컬럼을 보면 제대로 정렬된 것을 볼 수 있다.

WITH cte as (SELECT  id, student,
            CEIL( (ROW_NUMBER() OVER(ORDER BY id)) /  2) as group_num

            FROM    Seat)

SELECT   
        ROW_NUMBER() OVER(ORDER BY group_num, id DESC) as id, student
FROM    cte
ORDER BY 
        group_num, id DESC

근데 또 이렇게 하면

idstudent
2Abbot
1Doris
4Emerson
3Green
5Jeames

이렇게 나온다. 이건 쿼리문을 작성하다가 흔하게 할 수 있는 잘못인데,
위에서 작성한 대로 쿼리문을 그대로 사용하면서 별칭을 바꿨는데 ORDER BY group_num, id DESC가 그대로 남아있으면서 의도치 않은 재정렬이 되어버린 것이다.

answer

WITH cte as (SELECT  id, student,
            CEIL( (ROW_NUMBER() OVER(ORDER BY id)) /  2) as group_num

            FROM    Seat)

SELECT   
        ROW_NUMBER() OVER(ORDER BY group_num, id DESC) as id, student
FROM    cte

가장 편한 풀이는 그냥 CASE WHEN 사용해서 짝수일 때는 id - 1 하고 홀수일 때는 id + 1 한 다음에 id로 정렬하면 된다.

profile
열심히 하면 재밌다

0개의 댓글