Mysql__leecode/0626. 换座位

本文介绍如何使用SQL的CASE函数和MOD运算,以及位操作方法解决学校座位交换问题。通过案例解析和代码实例,帮助你理解如何在SQL中实现相邻学生座位的调整,尤其适用于奇数学生数量的情况。

一、刷题内容

原题链接

https://leetcode-cn.com/problems/exchange-seats/

内容描述

SQL架构
小美是一所中学的信息科技老师,她有一张 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  |
+---------+---------+

注意:
如果学生人数是奇数,则不需要改变最后一个同学的座位。

二、解题方法

1.方法一:使用 CASE 和 MOD 函数

对于所有座位 id 是奇数的学生,修改其 id 为 id+1,如果最后一个座位 id 也是奇数,则最后一个座位 id 不修改。对于所有座位 id 是偶数的学生,修改其 id 为 id-1。

首先查询座位的数量。

SELECT
    COUNT(*) AS counts
FROM
    seat

然后使用 CASE 条件和 MOD 函数修改每个学生的座位 id。

在 MySQL 中求余函数 MOD(x,y) 返回 x 被 y 除后的余数,MOD() 对于带有小数部分的数值也起作用,它返回除法运算后的余数。

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

2.方法二:使用位操作和 COALESCE()

使用 (id+1)^1-1 计算交换后每个学生的座位 id。

SELECT id, (id+1)^1-1, student FROM seat;
id(id+1)^1-1student
12Abbot
21Doris
34Emerson
43Green
56Jeames

然后连接原来的座位表和更新 id 后的座位表。

SELECT
    *
FROM
    seat s1
        LEFT JOIN
    seat s2 ON (s1.id+1)^1-1 = s2.id
ORDER BY s1.id;
idstudentidstudent
1Abbot2Doris
2Doris1Abbot
3Emerson4Green
4Green3Emerson
5Jeames

注:前两列来自表 s1,后两列来自表 s2。

最后输出 s1.id 和 s2.student。但是 id=5 的学生,s1.student 正确,s2.student 为 NULL。因此使用 COALESCE() 函数为最后一行记录生成正确的输出。

COALESCE(value,…)是一个可变参函数,可以使用多个参数。
作用:接受多个参数,返回第一个不为NULL的参数,如果所有参数都为NULL,此函数返回NULL;当它使用2个参数时,和IFNULL函数作用相同。

SELECT
    s1.id, COALESCE(s2.student, s1.student) AS student
FROM
    seat s1
        LEFT JOIN
    seat s2 ON ((s1.id + 1) ^ 1) - 1 = s2.id
ORDER BY s1.id;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

百里 Jess

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值