文章目录
  1. 1. 题目
  2. 2. 解题思路
  3. 3. 注意事项
  4. 4. 构造测试数据
  5. 5. 一种答案

题目

#197 Rising Temperature

解题思路

依然是 Ranking 类问题。首先构造一个临时表 tmpTable,里面构造一个临时变量 prevVal 储存上一个 Temperature 值,把比较结果储存在临时列 isRising;构造一个临时变量 prevDate 用于判断日期是否连续。然后 SELECT 所有临时表中 isRising = 1 AND isDateOk = 1 的行。最后最外层过滤其他列,只选出 Id 一列。

日期比较方法有以下几种,第一第二种差不多,第三种当 @preDate = NULL 时 DATE_ADD 函数会出错不建议使用

  • Date BETWEEN Date AND @prevDate + INTERVAL 1 DAY
  • Date > @prevDate AND Date <= @prevDate + INTERVAL 1 DAY
  • Date BETWEEN Date AND DATE_ADD(@prevDate, INTERVAL 1 DAY)
  • DATEDIFF(Date, @prevDate) = 1

注意事项

  • Date 列的数据是乱序排列,不像题中例子那样是顺序的

    ORDER BY 排序

  • 中间某些日期的温度数据缺失

    构造临时变量判断日期是否连续

构造测试数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
CREATE TABLE Weather (
Id INT,
Date DATE,
Temperature INT
);

DELETE FROM Weather;

-- 根据测试用例增加了容易出错的一些行
INSERT INTO Weather VALUES
(1, '2015-01-01', 10),
(2, '2015-01-02', 25),
(4, '2015-01-04', 30),
(3, '2015-01-03', 32),
(5, '2015-01-06', 35);

预期结果:

Id
2
3

一种答案

完整答案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
-- Runtime: 1115 ms
SELECT
Id
FROM
(SELECT
Id,
IF(Temperature > @prevVal, 1, 0) AS isRising,
IF(Date > @prevDate
AND Date <= @prevDate + INTERVAL 1 DAY, 1, 0) AS isDateOk,
@prevVal:=Temperature,
@prevDate:=Date
FROM
Weather, (SELECT @prevVal:=NULL) tmpVal, (SELECT @prevDate:=NULL) tmpDate
ORDER BY Date) tmpTable
WHERE
isRising = 1 AND isDateOk = 1

其中内层查询得到 tmpTable 的语句是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
SELECT 
Id,
IF(Temperature > @prevVal, 1, 0) AS isRising,
IF(Date > @prevDate
AND Date <= @prevDate + INTERVAL 1 DAY,
1,
0) AS isDateOk,
@prevVal:=Temperature,
@prevDate:=Date
FROM
Weather,
(SELECT @prevVal:=NULL) tmpVal,
(SELECT @prevDate:=NULL) tmpDate
ORDER BY Date

内层查询得到的临时表 tmpTable 结果是:

Id isRising isDateOk @prevVal:=Temperature @prevDate:=Date
1 0 0 10 2015-01-01
2 1 1 25 2015-01-02
3 1 1 32 2015-01-03
4 0 1 30 2015-01-04
5 1 0 35 2015-01-06

本博客微信公众号

文章目录
  1. 1. 题目
  2. 2. 解题思路
  3. 3. 注意事项
  4. 4. 构造测试数据
  5. 5. 一种答案