题目
小美是一所中学的信息科技老师,她有一张 seat
座位表,平时用来储存学生名字和与他们相对应的座位 id。
其中纵列的 id
是连续递增的
小美想改变相邻俩学生的座位。
你能不能帮她写一个 SQL query
来输出小美想要的结果呢?
示例:
id | student |
---|---|
1 | Abbot |
2 | Doris |
3 | Emerson |
4 | Green |
5 | Jeames |
假如数据输入的是上表,则输出结果如下:
id | student |
---|---|
1 | Doris |
2 | Abbot |
3 | Green |
4 | Emerson |
5 | Jeames |
注意:
如果学生人数是奇数,则不需要改变最后一个同学的座位。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/exchange-seats
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路分析
方法1: case
select
查询出来每个记录的时候, 可以使用case
判断当前记录的id
值为奇数还是偶数, 如果为奇数则输出id+1
, 如果为偶数则输出 id-1
, 但是如果记录的数量为奇数, 则最后一条的id
应该保持不变. 因此我们先查询出来记录的数量, 将其联结到表每个记录后面形成一个字段, 这样case
可以使用这个字段判断id
是否为最后一个记录.
select (
case MOD(id, 2) = 0 then id-1
case MOD(id, 2) != 0 and id != cnt then id + 1
else id
), student
from seat
join (select count(*) as cnt from seat) student_count;
order by id;
方法2: (id + 1)^1 - 1
使用上述公式, 如果id
为偶数, 则其会转换为id - 1
. 如果 id
为奇数, 则转换为 id + 1
, 我们可以根据这个公式进行左联结, 在对有用字段select
即可.
select
s1.id,
(
case
when ISNULL(s2.student)
then s1.student
else s2.student
) student
from
seat s1
left join
seat s2
on (s1.id + 1)^1 - 1 = s2.id