astak16/blog-mysql

29 换座位

Opened this issue · 0 comments

题目

题目链接:换座位

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

create table seat (
	id int,
	student varchar(255)
);

insert into seat values
(1, 'Doris'),
(2, 'Abbot'),
(3, 'Green'),
(4, 'Emerson'),
(5, 'Jeames');

SQL:方法一

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 count
order by id asc;

解析

  • mod(n, m)n 取余。
  • 先计算出一共有多少条数据,取名为 counts
  • mod 函数对 id 取余
    • 如果等于 0 ,说明是偶数,则 id - 1
    • 如果不等于 0 ,说明是奇数,并且 id 不等于 counts ,则 id + 1
    • 如果不等于 0 ,说明是奇数,并且 id 等于 counts ,则 id 不变

SQL:方法二

select s.id, 
	if(mod(s.id, 2) = 1, s.back, s.ahead) as student 
from (
	select 
		id, student,
		lag(student, 1, student) over() as ahead,
		lead(student, 1, student) over() as back
	from seat
) as s;

解析

  • 窗口函数 lag 从前往后取,跳过第一行, nullseat.student 来填充

    id student ahead
    1 Doris Doris
    2 Abbot Doris
    3 Green Abbot
    4 Emerson Green
    5 Jeames Emerson
  • 窗口函数 lead 从后往前取,跳过最后一行, nullseat.student 来填充

    id student back
    1 Doris Abbot
    2 Abbot Green
    3 Green Emerson
    4 Emerson Jeames
    5 Jeames Jeames
  • 再通过 mod 判断奇偶数,奇数取 back ,偶数取 ahead