【LeetCode-SQL】626. 换座位

目录

  • 一、题目
  • 二、解决
    • 1、if / case when
    • 2、row_number()
    • 3、left join
    • 4、异或
  • 三、参考

一、题目

表: Seat

+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| id          | int     |
| name        | varchar |
+-------------+---------+
Id是该表的主键列。
该表的每一行都表示学生的姓名和ID。
Id是一个连续的增量。

编写SQL查询来交换每两个连续的学生的座位号。如果学生的数量是奇数,则最后一个学生的id不交换。

id 升序 返回结果表。

查询结果格式如下所示。

示例 1:

输入: 
Seat:
+----+---------+
| 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、if / case when

思路:

主要根据 id 的奇偶性进行处理,这里要注意 id 最大值为基数的情况。
if id 为偶数,then id - 1;
if id为奇数且不为最大值, then id + 1;
if id为奇数且为最大值then id 不变。

代码 - 版本1:

select 
    if (id%2=0, id-1, 
    	if(id=mxid, id, id+1)
    ) as id, student 
from seat, (select max(id) as mxid from seat) as init # 最大数为奇数
order by id;

代码 - 版本2:

select 
    case 
        when id % 2 = 0 then id - 1
        when id % 2 = 1 and id = mxid then id
        else id + 1
    end as id
    , student
from seat, (select max(id) as mxid from seat) as init # 最大数为奇数
order by id;

2、row_number()

思路:

row_number() 作用实例:

SELECT 
  name, recovery_model_desc
FROM sys.databases 
WHERE database_id < 5
ORDER BY name ASC;

Here is the result set.

name recovery_model_desc
master SIMPLE
model FULL
msdb SIMPLE
tempdb SIMPLE
SELECT 
  ROW_NUMBER() OVER(PARTITION BY recovery_model_desc ORDER BY name ASC) 
    AS Row#,
  name, recovery_model_desc
FROM sys.databases WHERE database_id < 5;

Here is the result set.

Row# name recovery_model_desc
1 model FULL
1 master SIMPLE
2 msdb SIMPLE
3 tempdb SIMPLE

代码:

select 
    row_number() over(order by (id + 1 - 2 * power(0, id%2))) as id,
    student
from 
    seat

说明:

select power(0, 1) as odd, power(0, 0) as even;

# res:
{"headers": ["odd", "even"], "values": [
	[0.0, 1.0]
]}

3、left join

思路:

select t1.id, t2.student, t1.student
from seat as t1 
left join seat as t2 on (t1.id%2=1 && t1.id=t2.id-1) || (t1.id%2=0 && t1.id=t2.id+1) 
order by t1.id;
a.id b.student a.student
1 Doris Abbot
2 Abbot Doris
3 Green Emerson
4 Emerson Green
5 null Jeames

代码:

select t1.id, ifnull(t2.student, t1.student) as student 
from seat as t1 
left join seat as t2 on (t1.id%2=1 && t1.id=t2.id-1) || (t1.id%2=0 && t1.id=t2.id+1) 
order by t1.id;

4、异或

思路: 0^1=1, 1^1=0, 2^1=3, 3^1=2,以此类推。
代码:

select b.id, a.student 
from seat as a, seat as b, (select count(*) as cnt from seat) as c 
where b.id = 1^(a.id-1) + 1
# where a.id=1^(b.id-1) + 1 # 也可以这样写,更容易理解. 
							# If b.id is 偶数, then b.id-1; 
							# If b.id is 奇数, then b.id+1; 
 || (c.cnt%2 && b.id=c.cnt && a.id=c.cnt);

三、参考

1、换座位
2、简单 易懂 效率击败所有
3、其实是一道中学数学题
4、626. 换座位[官方题解的坑要避免]
5、看到没有异或方法,我就知道我的机会来了

你可能感兴趣的:(LeetCode-SQL,leetcode,sql,算法)