订阅更新

比昨天温度高的日期:相邻日期要真的相差一天

SQL 实战 123 题 · 第 12 题 简单 约 2 分钟读完

LeetCode 197 · LAG、日期差、自连接

本文目录
  1. 面试怎么回答
  2. 题意
  3. 表结构
  4. 思路
  5. 参考解法
  6. 易错点

面试怎么回答

关键是「昨天」按日历算,不是按行算。我会用自连接 DATEDIFF(w1.RecordDate, w2.RecordDate) = 1 关联前一天再比较温度;用 LAG 的话也要额外校验日期差为 1,否则缺数据的日子会拿前天的值来比。

先把这段讲顺;面试官追问时,再展开下面的原理和细节。

详细讲解

题意

天气表每天一条记录,找出温度比前一天高的记录 Id。注意记录日期可能不连续,「前一天」指的是日历上的昨天,不是表里的上一行。

表结构

  • Weather:Id(主键)、RecordDate(日期)、Temperature

思路

用 LAG 按日期取上一条记录的日期和温度,同时校验两条记录的日期差正好是 1 天,才算「昨天」。原解法里给 LAG 设的默认值只是为了让第一行不满足条件;更清楚的写法是不设默认值,第一行拿到 NULL,比较结果为未知自然被过滤。

参考解法

select 
Id
from 
(
select Id,RecordDate,Temperature,
lag(RecordDate,1,9999-99-99) over (order by RecordDate) yd,
lag(Temperature,1,999) over(order by RecordDate ) yt
from Weather 
)tmp
where Temperature >yt
and datediff(RecordDate,yd)=1

另一种写法:自连接写法,直接按「日期差 1 天」关联

SELECT w1.Id
FROM Weather w1
JOIN Weather w2 ON DATEDIFF(w1.RecordDate, w2.RecordDate) = 1
WHERE w1.Temperature > w2.Temperature

易错点

  • 只比较「上一行」不检查日期差:中间缺一天时,会拿前天的温度来比。
  • 原解法中 9999-99-99 没加引号,会被当成算术表达式,只是碰巧不影响结果;默认值不需要设置。
刷题进度保存在当前浏览器