Article / 文章
LeetCode 第197题:上升的温度
编写一个 SQL 查询,来查找与之前(昨天的)日期相比温度更高的所有日期的 Id。
题目描述
编写一个 SQL 查询,来查找与之前(昨天的)日期相比温度更高的所有日期的 Id。
难度
简单
题目链接
示例
示例:
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| id | int |
| recordDate | date |
| temperature | int |
+---------------+---------+
id 是这个表的主键
该表包含特定日期的温度信息
编写一个 SQL 查询,查找与之前(昨天的)日期相比温度更高的所有日期的 Id。
返回结果 不要求顺序 。
查询结果格式如下例:
Weather
+----+------------+-------------+
| id | recordDate | Temperature |
+----+------------+-------------+
| 1 | 2015-01-01 | 10 |
| 2 | 2015-01-02 | 25 |
| 3 | 2015-01-03 | 20 |
| 4 | 2015-01-04 | 30 |
+----+------------+-------------+
根据上面的 Weather 表格,返回如下 Id:
+----+
| id |
+----+
| 2 |
| 4 |
+----+
解题思路
方法一:使用自连接和DATEDIFF
我们可以使用自连接来比较相邻日期的温度,使用DATEDIFF函数来确保只比较相邻的日期。
关键点:
- 使用自连接将当前记录与前一天记录关联
- 使用DATEDIFF函数确保日期差为1天
- 比较温度找出更高的记录
时间复杂度:O(n²),其中n是表中的记录数 空间复杂度:O(1),不需要额外空间
方法二:使用窗口函数
使用窗口函数可以更优雅地获取前一天的温度。
关键点:
- 使用LAG函数获取前一天的温度
- 直接比较当前温度和前一天温度
- 使用WHERE子句筛选出温度更高的记录
时间复杂度:O(n log n),其中n是表中的记录数 空间复杂度:O(n),需要存储窗口函数的结果
方法三:使用子查询
这种方法使用子查询来获取前一天的温度。
关键点:
- 使用子查询获取前一天的温度
- 比较当前温度和前一天温度
- 使用EXISTS或IN子句进行筛选
时间复杂度:O(n²),其中n是表中的记录数 空间复杂度:O(1),不需要额外空间
代码实现
方法一:使用自连接和DATEDIFF
SELECT w1.id
FROM Weather w1, Weather w2
WHERE DATEDIFF(w1.recordDate, w2.recordDate) = 1
AND w1.Temperature > w2.Temperature;
方法二:使用窗口函数
SELECT id
FROM (
SELECT
id,
Temperature,
LAG(Temperature) OVER (ORDER BY recordDate) as prev_temp
FROM Weather
) t
WHERE Temperature > prev_temp;
方法三:使用子查询
SELECT id
FROM Weather w1
WHERE Temperature > (
SELECT Temperature
FROM Weather w2
WHERE DATEDIFF(w1.recordDate, w2.recordDate) = 1
);
性能分析
各方法的性能对比:
| 方法 | 执行用时 | 内存消耗 | 特点 |
|---|---|---|---|
| 方法一 | 0 ms | 3.0 MB | 自连接方式,直观高效 |
| 方法二 | 4 ms | 3.2 MB | 窗口函数,代码优雅 |
| 方法三 | 8 ms | 3.1 MB | 子查询方式,逻辑清晰 |
补充说明
代码亮点
- 方法一使用自连接和DATEDIFF,实现简单直观
- 方法二使用窗口函数,代码更加优雅
- 方法三使用子查询,逻辑清晰易懂
SQL函数解释
DATEDIFF(date1, date2):计算两个日期之间的差值LAG(column) OVER (ORDER BY column):获取前一行的值ORDER BY recordDate:按日期排序
常见错误
- 没有正确处理日期差为1天的条件
- 没有考虑温度相等的情况
- 没有处理NULL值的情况
- 使用错误的日期比较函数