跳转到主要内容
模块 7 · 第 3 课(共 4)课程中的27/57~12 min
模块课程(3/4)

LAG、LEAD 和运行总计

LAG 和 LEAD 是两个特殊的窗口函数,可让您访问 同一分区的 其他行:前一行 (LAG) 或 根据窗口的 ORDER BY 的下一个 (LEAD)。他们是 行间比较(增量、变化、间隔)的首选工具 并与 SUM/AVG/COUNT OVER 结合使用 运行总计。

LAG:上一行

SQL
LAG(colonna)            OVER (PARTITION BY p ORDER BY o)
LAG(colonna, n)         OVER (PARTITION BY p ORDER BY o)   -- n righe indietro
LAG(colonna, n, default) OVER (PARTITION BY p ORDER BY o)  -- default se non c'è

示例:对于每个订单,“自上一个订单以来的天数 客户”:

SQL
SELECT id,
       customer_id,
       ordered_at,
       ordered_at - LAG(ordered_at) OVER (
         PARTITION BY customer_id ORDER BY ordered_at
       ) AS since_previous_order
FROM   orders
ORDER BY customer_id, ordered_at;

每个客户的第一个订单都有 since_previous_order = NULL 因为 分区中没有“上一个”。

LEAD:下一行

LAG 的镜像。典型:“距离下一个事件的时间”、“差异 与下一个版本”。

SQL
SELECT id, ordered_at,
       LEAD(ordered_at) OVER (PARTITION BY customer_id ORDER BY ordered_at)
         - ordered_at AS to_next
FROM   orders;

运行总计:使用 OVER 进行聚合

聚合函数(SUM、AVG、COUNT、MAX、MIN)变为 累积与 OVER (… ORDER BY …) 结合使用时:

SQL
SELECT order_id,
       total,
       SUM(total) OVER (
         PARTITION BY customer_id
         ORDER BY     ordered_at
       ) AS running_total
FROM   …;

对于每一行, SUM 计算分区中所有行的总和 那个点,根据窗口的 ORDER BY。结果是 经典的“运行平衡”。

尝试一下

锻炼#sql.m7.l3.e1
尝试:0加载中...

对于每个订单,显示 id、customer_id、ordered_at 和 days_from_previous 列,该列是当前订单与同一客户的上一个订单之间的整天数(带 FLOOR),按 order_at 排序。如果没有先前的订单,则为 NULL。按 customer_id 和ordered_at 订购。

正在加载编辑器...
显示提示

LAG(ordered_at) OVER (PARTITION BY customer_id ORDER BYordered_at) 返回客户先前订单的时间戳。减去得到 INTERVAL,然后转换为天数。

3 次尝试后可用的解决方案

复习练习

锻炼#sql.m7.l3.e2
尝试:0加载中...

对于每个已交付的订单(状态 =“已交付”),显示 id、customer_id、ordered_at、order_total(其订单项的数量 * 单位价格之和)和 running_total(每个客户的总计的运行总计,按 order_at 排序)。使用 CTE 作为 order_total。按 customer_id 和ordered_at 订购。

正在加载编辑器...
显示提示

CTE 计算每个订单的总数; SUM OVER 生成每个客户随时间变化的运行总计。

3 次尝试后可用的解决方案