题目

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

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

解答

解法一

根据自己的逻辑尝试了一下,居然提交通过,哈哈!

---- MySQL ----
# Write your MySQL query statement below
select case when b.cnt % 2 = 0 then
                case when a.id % 2 = 0 then id - 1
                     when a.id % 2 = 1 then id + 1 end
            when b.cnt % 2 = 1 then
                case when a.id < b.cnt then
                    case when a.id % 2 = 0 then id - 1
                         when a.id % 2 = 1 then id + 1 end
                else id end
        end as id,
        student
from seat a,
(
    select count(*) as cnt
    from seat
) b
order by id; ---- 126ms

引入总行数计数 cnt ,作为另外一个表;

判断当前行数是偶数还是奇数,再判断当前 id 是奇数还是偶数,奇数+1,偶数 -1,依次类推;

当行数为奇数时,最后一行 id 不作任何操作。

简化一下。

---- MySQL ----
# Write your MySQL query statement below
select if(id % 2 = 0,
          id - 1,
          if(id = cnt,
             id,
             id + 1
            )
          ) as id,
       student
from
(
    select count(*) as cnt from seat
) as a,
seat
order by id; ---- 133ms

另一种。

---- MySQL ----
# Write your MySQL query statement below
select (case when id % 2 = 0 then id -1
             when id = (select max(id) from seat) then id
        else id + 1 end) as id,
       student
from seat
order by id; ---- 156ms

解法二

通过左连接的方法。

---- MySQL ----
# Write your MySQL query statement below
select a.id,
       ifnull(b.student, a.student) as student
from seat a
left join seat b
on (a.id % 2 = 1 && a.id = b.id -1) || (a.id % 2 = 0 && a.id = b.id + 1)
order by a.id ---- 135ms

真的很天才,佩服!

解法三

通过异或的方法,更是牛逼!

0 ^ 1 = 1

1 ^ 1 = 0

---- MySQL ----
select b.id,
       a.student
from seat a,
     seat b,
     (select count(*) as cnt from seat) c
where b.id = 1 ^ (a.id - 1) + 1 || (c.cnt % 2 && b.id = c.cnt && a.id = c.cnt); ---- 132ms

如果是一个偶数^1,结果是偶数+1;

如果是一个奇数^1,结果是奇数-1;

(id -1 ) ^ 1 + 1 可以把1、2交换位置,3、4交换位置。

思考

MySQL 中的 ifnull() 函数用于判断第一个表达式是否为 null ,如果为 null 则返回第二个表达式的值。

异或操作,真是神,往往能达到意想不到的效果,get!

02-01 01:23