这个问题类似于SQL Server LAG() function to calculate differences between rows,除了该示例使用DATEDIFF()
。假设我有一个表Weather
,其中有列RecordDate
和Temperature
。我想选择与前一天相比较高的Temperature
对应的行。
例如,如果Weather
像这样,
mysql> select * from weather;
+----+------------+-------------+
| id | RecordDate | Temperature |
+----+------------+-------------+
| 5 | 2000-12-16 | 3 |
| 6 | 2000-12-15 | -1 |
+----+------------+-------------+
我想选择第二天,
+----+------------+-------------+
| id | RecordDate | Temperature |
+----+------------+-------------+
| 5 | 2000-12-16 | 3 |
+----+------------+-------------+
因为那天3
的温度高于前一天-1
的温度。
我喜欢这个查询,它遵循https://dev.mysql.com/doc/refman/8.0/en/window-function-descriptions.html#function_lag的示例,我快到了:
mysql> select id, recorddate, temperature,
lag(temperature) over w as 'lag'
from weather
window w as (order by recorddate);
+----+------------+-------------+------+
| id | recorddate | temperature | lag |
+----+------------+-------------+------+
| 6 | 2000-12-15 | -1 | NULL |
| 5 | 2000-12-16 | 3 | -1 |
+----+------------+-------------+------+
剩下的就是选择temperature
大于lag
的行。但是,如果在查询末尾添加where temperature > lag
,则会收到语法错误:
mysql> select id, recorddate, temperature,
lag(temperature) over w as 'lag'
from weather
window w as (order by recorddate)
where temperature > lag;
错误1064(42000):您的SQL语法有错误;检查 与您的MySQL服务器版本相对应的手册 在第1行的“温度>滞后”附近使用的语法
有什么方法可以只维护中间结果中temperature > lag
的行吗?
答案 0 :(得分:2)
解决此问题的一种方法是利用Correlated Subqueries(在MySQL的较早版本中也可以使用)。我们可以使用子查询根据前一个日期获取每行的前一个温度,然后使用self.my_method
子句过滤掉当前温度高于前一个温度的情况:
查询#1
HAVING
仅适用于MySQL 8 + :我们仍然可以使用LAG()
函数解决此问题,但不能直接解决。到目前为止,MySQL在SELECT w1.id, w1.recorddate, w1.temperature,
(SELECT w2.temperature
FROM weather AS w2
WHERE w2.RecordDate < w1.RecordDate
ORDER BY w2.RecordDate DESC LIMIT 1) AS prev_temperature
FROM weather AS w1
HAVING w1.temperature > prev_temperature;
| id | recorddate | temperature | prev_temperature |
| --- | ---------- | ----------- | ---------------- |
| 5 | 2000-12-16 | 3 | -1 |
子句中抱怨如果我们尝试使用Window函数:
WHERE
错误:在这种情况下,您不能使用窗口函数“ lag”。
或者,如果我们尝试计算表达式中的先前温度,并使用SELECT id, RecordDate, temperature
FROM weather
WHERE temperature > LAG(temperature) OVER (ORDER BY RecordDate);
子句中的别名进行过滤:
HAVING
错误:您不能使用表达式的别名“ prev_temperature” 在这种情况下包含一个窗口函数。
因此,我们可以使用的一种方法是计算每行的所有先前温度值,并将此子查询用作Derived Table,以过滤掉外部SELECT id, RecordDate, temperature,
LAG(temperature) OVER (ORDER BY RecordDate) AS prev_temperature
FROM weather
HAVING temperature > prev_temperature;
查询。
查询#2
Select