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 位置
- 查询最大的 id
select max(id) as max_id from Seat
查询结果
+------+
|max_id|
+------+
|5 |
+------+
- 对
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 位置
- 对
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 |
+--+-------+