SQL

[Leetcode/SQL] 626. Exchange Seats

지구인 ㅣ 2022. 8. 23. 16:46

728x90
문제는 여기서 확인할 수 있습니다.

 

Table: Seat

+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| id          | int     |
| student     | varchar |
+-------------+---------+
id is the primary key column for this table.
Each row of this table indicates the name and the ID of a student.
id is a continuous increment.

 

Write an SQL query 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.

The query result format is in the following example.

 

Example 1:

Input: 
Seat table:
+----+---------+
| id | student |
+----+---------+
| 1  | Abbot   |
| 2  | Doris   |
| 3  | Emerson |
| 4  | Green   |
| 5  | Jeames  |
+----+---------+
Output: 
+----+---------+
| id | student |
+----+---------+
| 1  | Doris   |
| 2  | Abbot   |
| 3  | Green   |
| 4  | Emerson |
| 5  | Jeames  |
+----+---------+
Explanation: 
Note that if the number of students is odd, there is no need to change the last one's seat.

 

Code:

/*
- COALESCE(a, b) : a가 있으면(b가 있더라도) a를 반환, a가 없고 b는 있으면 b를 반환
- ^	: XOR 연산을 수행한다. (대응 하는 비트가 서로 다르면 1을 반환한다.)
*/

SELECT s1.id, COALESCE(s2.student, s1.student) AS student
FROM seat s1
LEFT JOIN seat s2
ON ((s1.id + 1) ^ 1) - 1 = s2.id
ORDER BY s1.id;

/*
- case when : id -> 짝수는 -1, 홀수는 +1, 단 마지막 id가 홀수면 그대로 둔다
*/

SELECT
    (CASE
        WHEN MOD(id, 2) != 0 AND counts != id THEN id + 1
        WHEN MOD(id, 2) != 0 AND counts = id THEN id
        ELSE id - 1
    END) AS id,
    student
FROM
    seat,
    (SELECT
        COUNT(*) AS counts
    FROM
        seat) AS seat_counts
ORDER BY id ASC;

생각보다 문제가 쉽지 않아 예시 solution을 참고했다.

- 새로 알게 된 것 : mod(), coalesce()

 

첫번째 풀이

- coalesce(a, b) : 두 테이블을 조인하면 두번째 테이블의 마지막 student가 null이다. 그리고 마지막 학생은 원래의 student 그대로 가야한다. 왜냐하면 총 학생 수가 홀수이기 때문에 마지막 학생은 id를 바꿀 다음 학생이 없게 되기 때문이다.

따라서 문제의 요구사항에 따라 순서를 바꾼 두번째 테이블에는 마지막 학생이 null이다. 그러므로 coalesce를 통해 우선적으로 두번째 테이블의 student를 select하되, null일 시에는 첫번째 테이블의 student를 select할 수 있도록 한다.

 

두번째 풀이

- mod는 이름에서 알 수 있듯이, 나눗셈의 나머지를 구하는 함수이다. case when 구문을 살펴보면 id가 짝수일 시 -1, 홀수일 시 +1, 만약 홀수인데 마지막 id라면 덧셈연산 없이 그대로 두는 연산을 한다. 그렇게 요구사항에 맞게 id를 변경한다.

- select count(*) as counts from seat의 결과는 숫자 5이다. 쿼리 없이 그냥 숫자 5와 계산할 수 없는 건가...? 싶었는데 예시 코드는 어쨌거나 위와 같았다.

 

다른 풀이를 보면 if함수를 사용하기도 했는데 잘 사용하면 여러모로 편한 함수일 듯하다. 자주 사용하려고 노력해야겠다.

728x90