SQL每日一练

题目:在一个有连续日期气温记录的表格中,找出气温比前一天有身高的日期。只需输出日期,升序输出结果。

两个字段:date、temperature

理清解题关键:

  1. 获取前一天的温度:对于每一天,都需要知道前一天的温度值

  2. 进行比较:判断当天温度是否大于前一天温度

  3. 筛选结果:只保留满足条件的日期

方法一:使用SELF JOIN

sql 复制代码
SELECT t1.date
FROM temperatures t1
INNER JOIN temperatures t2
  ON DATEDIFF (t1.date,t2.date)=1
  AND t1.temperature > t2.temperature
ORDER BY t1.date ASC
;

①SELF JOIN

使用自连接SELF JOIN,一张表分为两个表用,(FROM)一个表是当前天的温度,(INNER JOIN)另一个表是对比天的温度。(ON的内容)用前后一天的日期来联合,(AND)并且后一天气温必须大于前一天。

②DATEDIFF函数:

sql 复制代码
DATEDIFF(date1, date2)
DATEDIFF(较晚日期, 较早日期)

返回date1和date2 之间的天数差(date1-date2),以这里为例,天数差为1则输入为=1;

这个函数找到了前后一天的日期,那么还需要温度方面的大小就得加个AND;

再加上order by的内容就完成题目要求了!

方法二:窗口函数LAG()

这里的逻辑是利用lag函数得到前一行的温度数据,利用子查询从lag函数返回的数据中筛选出后一天温度比前一天温度高的那些日期。

sql 复制代码
SELECT date
FROM (
    SELECT 
        date,
        temperature,
        LAG(temperature) OVER (ORDER BY date) AS prev_temp
    FROM temperatures
) t
WHERE prev_temp IS NOT NULL 
  AND temperature > prev_temp
ORDER BY date;

①LAG函数

一个可以帮助你"回头看"上一行(或前几行)的值 ,而无需使用复杂的自连接的窗口函数。

sql 复制代码
LAG(column_name, offset, default_value) OVER (
    [PARTITION BY partition_expression]
    ORDER BY order_expression [ASC | DESC]
)

必填:column name是想要获取的前一行的值的列名字(比如这里是想获得上一行的温度)

order by是前一行"和"后一行"是基于哪个字段的顺序来判定的(这里就是基于日期对温度进行排列)

选填:offset是回溯的行数,是要回溯一行两行还是多少行;default_value是第一行前面没有数值的情况下返回什么值。

注意:记得这里的子查询要起一个别名每个派生表都必须有自己的别名,否则会报错。

好的今天记录与分享为以上内容,感谢阅读!