You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL相邻学生座位互换CASE WHEN实现及其他简便解法咨询

更简洁的CASE语句实现

你原来的写法需要重复查询max(id),可以用窗口函数LEAD/LAG简化逻辑,不需要单独判断最后一个奇数id的特殊情况,可读性和执行效率都更高:

SELECT
    id,
    CASE
        WHEN MOD(id, 2) = 1 THEN LEAD(student, 1, student) OVER(ORDER BY id)
        ELSE LAG(student) OVER(ORDER BY id)
    END AS student
FROM seat
ORDER BY id

逻辑说明:

  • 奇数id的行,取下一行的学生名,如果是最后一行没有下一行,就默认取当前行的学生名
  • 偶数id的行,取上一行的学生名
  • 不需要修改原id字段,省去了排序前重新算id的步骤

如果你用的数据库不支持窗口函数,可以用CTE提前取出最大id,避免重复子查询:

WITH max_id_info AS (SELECT MAX(id) AS max_id FROM seat)
SELECT
    CASE
        WHEN id = max_id AND MOD(max_id, 2) = 1 THEN id
        WHEN MOD(id, 2) = 1 THEN id + 1
        ELSE id - 1
    END AS id,
    student
FROM seat, max_id_info
ORDER BY id

其他实现思路

1. 自连接实现

不用CASE语句,通过左连接匹配相邻行的学生信息:

SELECT
    s1.id,
    COALESCE(s2.student, s1.student) AS student
FROM seat s1
LEFT JOIN seat s2 
ON (s1.id % 2 = 1 AND s1.id + 1 = s2.id) 
OR (s1.id % 2 = 0 AND s1.id - 1 = s2.id)
ORDER BY s1.id

2. 排序偏移重编号实现

通过对奇偶id做偏移排序,再用窗口函数重新生成id,逻辑非常简洁:

SELECT
    ROW_NUMBER() OVER(ORDER BY IF(MOD(id,2)=1, id+0.1, id-0.1)) AS id,
    student
FROM seat

逻辑说明:给奇数id加0.1,偶数id减0.1,排序后相邻的奇偶id会交换顺序,重新编号后直接得到目标id。

3. IF函数简化(适用于MySQL等支持IF函数的数据库)

如果不限制必须用CASE,用IF函数可以把代码压得更短:

SELECT
    IF(MOD(id,2)=1 AND id=(SELECT MAX(id) FROM seat), id, IF(MOD(id,2)=1, id+1, id-1)) AS id,
    student
FROM seat
ORDER BY id

内容的提问来源于stack exchange,提问作者vegetarianCoder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 18:06:04