题目

题目起源:回升的温度

形容:查找与之前(昨天)日期相比温度更高的所有日期的 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 w1on datediff(weather.recordDate, w1.recordDate) = 1and weather.temperature > w1.temperature;

解析

只有一张表,当初要找出明天温度比昨天温度高的日期 id

所以须要用自连贯,也就是把 weatherweather 进行本身连贯。

在自连之后,须要将自连后的表取个别名 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) tempwhere 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;
idrecordDatetemperaturenextIdnextDatenextTemp
12015-01-011022015-01-0225
22015-01-022532015-01-0320
32015-01-032042015-01-0430
42015-01-0430nullnullnull

这里说一下,窗口函数还有一个 lag 是从返回后偏移的,用法和 lead 是一样的。这里就用 lead 来举例。

前三列是 weather 原数据,后三列是应用窗口函数 lead 算进去的数据。

为什么是偏移 1 呢?

因为比拟的是明天和昨天,而且这里日期是间断的,所以用 1

而后查问进去的数据作为一个长期表 temp

筛选条件就是 nextTemp > temperature ,最初应用 datediff 比拟两个日期差可写可不写,因为这里日期是间断的。

更多解题参考:https://github.com/astak16/bl...