LeetCode--626. 换座位

44 阅读2分钟

1 题目描述

表: Seat

+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| id          | int     |
| student     | varchar |
+-------------+---------+

id 是该表的主键 (唯一值) 列 该表的每一行都表示学生的姓名和 ID id 是一个连续的增量

编写解决方案来交换每两个连续的学生的座位号. 如果学生的数量是奇数, 则最后一个学生的 id 不交换 按 id 升序 返回结果表

2 测试用例

输入: Seat 表:

+----+---------+
| id | student |
+----+---------+
| 1  | Abbot   |
| 2  | Doris   |
| 3  | Emerson |
| 4  | Green   |
| 5  | Jeames  |
+----+---------+

输出:

+----+---------+
| id | student |
+----+---------+
| 1  | Doris   |
| 2  | Abbot   |
| 3  | Green   |
| 4  | Emerson |
| 5  | Jeames  |
+----+---------+

解释: 请注意, 如果学生人数为奇数, 则不需要更换最后一名学生的座位

3 解题思路

3.1 解法 1: 交换 id 位置

  1. 查询最大的 id
select max(id) as max_id from Seat

查询结果

+------+
|max_id|
+------+
|5     |
+------+
  1. id 进行条件匹配, 三种场景, 最后需要对 id 做升序排序

奇数场景且不是最后一个座位 id % 2 = 1 and id != mi.max_id: 执行 id + 1 奇数场景且是最后一个座位 id % 2 = 1 and id = mi.max_id: 不处理 偶数场景 id % 2 =0: 执行 id -1

select (case
            when id % 2 = 1 and id != mi.max_id then id + 1
            when id % 2 = 1 and id = mi.max_id then id
            else id - 1 end) as id,
       student
from Seat,
     (select max(id) as max_id from Seat) as mi
order by id;

查询结果

+--+-------+
|id|student|
+--+-------+
|1 |Doris  |
|2 |Abbot  |
|3 |Green  |
|4 |Emerson|
|5 |Jeames |
+--+-------+

这种解法存在一个风险点: 交换的是主键, 在现实的开发过程中是不允许的

3.2 解法 2: 交换 student 位置

  1. id 进行奇偶数判断

奇数场景: 使用 lead(student, 1, student) over (order by id) 将下一行的 student 换到当前行, 如果当前行是最后一行, 意味着下一行为 null, 设置默认值为 student 偶数场景: 使用 lag(student, 1) over (order by id) 将上一行的 student 换到当前行

select id,
       if(id % 2 = 1,
          lead(student, 1, student) over (order by id),
          lag(student, 1) over (order by id)
       ) as student
from Seat;

查询结果

+--+-------+
|id|student|
+--+-------+
|1 |Doris  |
|2 |Abbot  |
|3 |Green  |
|4 |Emerson|
|5 |Jeames |
+--+-------+