共计 1748 个字符,预计需要花费 5 分钟才能阅读完成。
题目
题目起源:回升的温度
形容:查找与之前(昨天)日期相比温度更高的所有日期的 id
。
应用的是 MySQL8.0
,没有在 MySQL5.6
版本中测验过,不保障正确。
create table weather (
id int primary key auto_increment,
recordDate date,
temperature int
);
insert into weather(recordDate, temperature) values
('2015-01-01', 10),
('2015-01-02', 25),
('2015-01-03', 20),
('2015-01-04', 30);
SQL:办法一
select weather.id from weather join weather w1
on datediff(weather.recordDate, w1.recordDate) = 1
and weather.temperature > w1.temperature;
解析
只有一张表,当初要找出明天温度比昨天温度高的日期 id
。
所以须要用自连贯,也就是把 weather
和 weather
进行本身连贯。
在自连之后,须要将自连后的表取个别名 w1
,如果不取别名的话,两个 weather
表名会抵触。这里把 weather
作为明天表,w1
作为昨天表。
两表自连之后须要有连贯条件,连贯条件是 明天和昨天的日期 。
MySQL 提供了 datediff
函数,用来比拟两个日期之间的时间差,如果两个工夫之间相差 1
天,那么就是明天和做题。
最初在筛选出明天的温度高于昨天温度的数据。
SQL:办法二
select weather.id from weather join weather w1
on weather.recordDate = adddate(w1.recordDate, interval 1 day)
and weather.temperature > w1.temperature;
解析
思路和办法一的思路是一样的,区别在于计算明天和昨天的办法不一样。
这里应用 MySQL 提供的 adddate
函数。这个函数是将日期函数一个法则进行偏移。
SQL:办法三
select id from (
select
temperature,
recordDate ,
lead(id, 1) over(order by recordDate) as id,
lead(recordDate, 1) over(order by recordDate) as 'nextDate',
lead(temperature, 1) over(order by recordDate) as 'nextTemp'
from weather
) temp
where nextTemp > temperature and datediff(nextDate, recordDate) = 1;
解析
应用窗口函数 lead
,它是从后往前偏移,偏移量为 1
天。
select
temperature,
recordDate ,
lead(id, 1) over(order by recordDate) as nextId,
lead(recordDate, 1) over(order by recordDate) as 'nextDate',
lead(temperature, 1) over(order by recordDate) as 'nextTemp'
from weather;
id | recordDate | temperature | nextId | nextDate | nextTemp |
---|---|---|---|---|---|
1 | 2015-01-01 | 10 | 2 | 2015-01-02 | 25 |
2 | 2015-01-02 | 25 | 3 | 2015-01-03 | 20 |
3 | 2015-01-03 | 20 | 4 | 2015-01-04 | 30 |
4 | 2015-01-04 | 30 | null | null | null |
这里说一下,窗口函数还有一个 lag
是从返回后偏移的,用法和 lead
是一样的。这里就用 lead
来举例。
前三列是 weather
原数据,后三列是应用窗口函数 lead
算进去的数据。
为什么是偏移 1
呢?
因为比拟的是明天和昨天,而且这里日期是间断的,所以用 1
。
而后查问进去的数据作为一个长期表 temp
。
筛选条件就是 nextTemp > temperature
,最初应用 datediff
比拟两个日期差可写可不写,因为这里日期是间断的。
更多解题参考:https://github.com/astak16/bl…