小美是一所中学的信息科技老师,她有一张 seat 座位表,平时用来储存学生名字和与他们相对应的座位 id。

其中纵列的 id 是连续递增的

小美想改变相邻俩学生的座位。

你能不能帮她写一个 SQL query 来输出小美想要的结果呢?

示例:

  1. +---------+---------+
  2. | id | student |
  3. +---------+---------+
  4. | 1 | Abbot |
  5. | 2 | Doris |
  6. | 3 | Emerson |
  7. | 4 | Green |
  8. | 5 | Jeames |
  9. +---------+---------+

假如数据输入的是上表,则输出结果如下:

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

注意:

如果学生人数是奇数,则不需要改变最后一个同学的座位。
解决思路:看网上人写的,大致上明白了。当为偶数的时候 id - 1 ,当为奇数的时候并且id不是最后id的时候id + 1 ,当最后一个id为奇数的时候,则不交换,然后使用union合并

MySQL UNION 操作符

MySQL UNION 操作符用于连接两个以上的 SELECT 语句的结果组合到一个结果集合中。多个 SELECT 语句会删除重复的数据。
我的SQL:

SELECT
    a.id,
    a.student
FROM
    (
        SELECT
            id - 1 id,
            student
        FROM
            seat
        WHERE
            MOD (id, 2) = 0
        UNION
            SELECT
                id + 1 id,
                student
            FROM
                seat
            WHERE
                MOD (id, 2) = 1
            AND id != (SELECT count(*) FROM seat)
            UNION
                SELECT
                    id,
                    student
                FROM
                    seat
                WHERE
                    MOD (id, 2) = 1
                AND id = (SELECT count(*) FROM seat)
    ) a
ORDER BY
    id

其他高级SQL:
对照上表及其查询结果可以得知,当原id为奇数时,交换座位后的id变为id+1,当原id为偶数时,交换座位后的id变为id-1,另一个方面需要考虑的是,学生人数为奇数时,最后一个学生的id不变,故应当用子查询确定学生的人数,然后分情况讨论即可。

SELECT
    (
        CASE
        WHEN MOD (id, 2) != 0
        AND id != counts THEN
            id + 1
        WHEN MOD (id, 2) != 0
        AND id = counts THEN
            id
        ELSE
            id - 1
        END
    ) AS id,
    student
FROM
    seat,
    (
        SELECT
            count(*) AS counts
        FROM
            seat
    ) AS seat_counts
ORDER BY
    id;