626. 换座位
难度中等
题目描述
表: Seat
+-------------+---------+ | Column Name | Type | +-------------+---------+ | id | int | | student | varchar | +-------------+---------+ id 是该表的主键(唯一值)列。 该表的每一行都表示学生的姓名和 ID。 ID 序列始终从 1 开始并连续增加。
编写解决方案来交换每两个连续的学生的座位号。如果学生的数量是奇数,则最后一个学生的id不交换。
按 id 升序 返回结果表。
查询结果格式如下所示。
示例 1:
输入: 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 | +----+---------+ 解释: 请注意,如果学生人数为奇数,则不需要更换最后一名学生的座位。
解法
方法一
思考
相邻奇偶座位互换,最后一人若落单则不动。自连接可按「配对 id」取对方姓名。
(id+1)^1-1 把奇数映到下一偶数、偶数映到上一奇数。左连接后 COALESCE 在没有搭档时保留原名。
1 2 3 4 5 6 | |
方法二
思考
也可不连表,直接改 id:非末奇数加一、偶数减一、末奇数不变,再按新 id 排序,效果与换人相同。
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
方法三
思考
把 \(0\) 起始的下标做异或翻转,再用 RANK 得到新座位号,一行即可表达成对交换,末位因没有配对自然保持相对顺序。
1 2 3 4 5 | |
方法四
思考
方法二用子查询取最大 id 判断末行。亦可用 ROW_NUMBER 与窗口 COUNT 比较是否最后一行,避免再扫一遍表。
1 2 3 4 5 6 7 8 9 10 | |