• SQL必会——常见时间数据的处理


    【题目】

    下面是某公司每天的营业额,表名为“日销”。“日期”这一列的数据类型是日期类型(date)。

    请找出所有比前一天(昨天)营业额更高的数据。(前一天的意思,如果“当天”是1月,“昨天”(前一天)就是1号)

    【解题思路】

    1.交叉联结

    首先我们来复习一下之前课程《从零学会sql》里讲过的交叉联结(corss join)的概念。

    使用交叉联结会将两个表中所有的数据两两组合。如下图,是对表“text”自身进行交叉联结的结果:

     

    直接使用交叉联结的业务需求比较少见,往往需要结合具体条件,对数据进行有目的的提取,本题需要结合的条件就是“前一天”。

    2.本题的日销表交叉联结的结果(部分)如下。这个交叉联结的结果表,可以看作左边三列是表a,右边三列是表b。

     红色框中的每一行数据,左边是“当天”数据,右边是“前一天”的数据。比如第一个红色框中左边是“当天”数据(2号),右边是“前一天”的数据(1号)。

    题目要求,销售额条件是:“当天” > “昨天”(前一天)。所以,对于上面的表,我们只需要找到表a中销售额(当天)大于b中销售额(昨天)的数据。

    3.另一个需要着重去考虑的,就是如何找到 “昨天”(前一天),这里为大家介绍两个时间计算的函数:

    datediff(日期1, 日期2):

    得到的结果是日期1与日期2相差的天数。

    如果日期1比日期2大,结果为正;如果日期1比日期2小,结果为负。

    例如:日期1(2019-01-02),日期2(2019-01-01),两个日期在函数里互换位置,就是下面的结果

     另一个关于时间计算的函数是:

    timestampdiff(时间类型, 日期1, 日期2)

    这个函数和上面diffdate的正、负号规则刚好相反。

    日期1大于日期2,结果为负,日期1小于日期2,结果为正。

    在“时间类型”的参数位置,通过添加“day”, “hour”, “second”等关键词,来规定计算天数差、小时数差、还是分钟数差。示例如下图:

    【解题步骤】

    1.将日销表进行交叉联结

    2.选出上图红框中的“a.日期比b.日期大一天”

    可以使用“diffdate(a.日期, b.日期) = 1”或者“timestampdiff(day, a.日期, b.日期) = -1”,以此为基准,提取表中的数据,这里先用diffdate进行操作。

    代码部分:

    1. select *
    2. from 日销 as a cross join 日销 as b
    3. on datediff(a.日期, b.日期) = 1;

     

     

    3.找出a中销售额大于b中销售额的数据

    where a.销售额(万元) > b.销售额(万元)

    得到结果:

    4.删掉多余数据

    题目只需要找销售额大于前一天的ID、日期、销售额,不需要上表那么多数据。所以只需要提取中上表的ID、日期、销售额(万元)列。

    结合一开始提到的两个处理时间的方法,最终答案及结果如下:

    1. select a.ID, a.日期, a.销售额(万元)
    2. from 日销 as a cross join 日销 as b
    3. on datediff(a.日期, b.日期) = 1
    4. where a.销售额(万元) > b.销售额(万元);

     或者:

    1. select a.ID, a.日期, a.销售额(万元)
    2. from 日销 as a cross join 日销 as b
    3. on timestampdiff(day, a.日期, b.日期) = -1
    4. where a.销售额(万元) > b.销售额(万元);

     

    还可以用到SQL的偏移函数:LAG 和LEAD 

     LAG、LEAD
    允许我们从窗口分区中,根据给定的相对于当前行的前偏移量(LAG)或后偏移量(LEAD),并返回对应
    行的值,默认的偏移量为1。当指定的偏移量没有对用的行是,LAG 和LEAD 默认返回 NULL,当然可用其他
    值替换  LAG(val,1,0.00) 第3个参数就是替换值。

     

    1. SELECT *,
    2. LAG(ProductPrice) OVER(ORDER BY ProductPrice) AS PreValue,
    3. LEAD(ProductPrice) OVER(ORDER BY ProductPrice) AS NextValue
    4. FROM OrderInfo

    【举一反三】

    下面是气温表,名为weather,date列的数据格式为date,请找出比前一天温度更高的ID和日期

    参考答案:

    1. select a.ID, a.date
    2. from weather as a cross join weather as b
    3. on datediff(a.date, b.date) = 1
    4. where a.temp > b.temp;

     或者

    1. select a.ID, a.date
    2. from weather as a cross join weather as b
    3. on timestampdiff(day, a.date, b.date) = -1
    4. where a.temp > b.temp;

     

    转载于公众号:猴子数据分析 

  • 相关阅读:
    2051. The Category of Each Member in the Store
    【科技素养】蓝桥杯STEMA 科技素养组模拟练习试卷C
    Worthington丨Worthington胶原酶原材料认证
    Eolink征文活动---Eolink API文档服务的天才产品
    系统架构设计:16 论软件开发过程RUP及其应用
    分布式系统的自我管理——反馈控制模型
    【必知必会的MySQL知识】④DCL语言
    Docker游戏Dos小游戏,一个web版的dos游戏库
    练习敲代码速度
    【MySQL系列】使用C语言来连接数据库
  • 原文地址:https://blog.csdn.net/qq_41404557/article/details/126123304