SQL中Lag()和LEAD()的用法示例详解

 更新时间:2025年10月28日 09:28:56   作者:王旭亮_  
LAG和LEAD函数为SQL开发者提供了强大的数据洞察力,尤其是在处理时间序列和趋势分析问题时,下面这篇文章主要介绍了SQL中Lag()和LEAD()用法的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下

前言

LAG() 和 LEAD() 是 SQL 中常用的窗口函数,核心作用是在同一结果集中,根据指定排序规则,获取当前行“前面”或“后面”某行的数据,无需进行自连接,极大简化了“跨行取值”的逻辑。

一、核心定义与语法

两者语法结构完全一致,仅功能相反(LAG 取前,LEAD 取后)。

基本语法

LAG(目标字段, 偏移量, 默认值) OVER (

    PARTITION BY 分组字段  -- 可选:按某字段分组,组内独立计算

    ORDER BY 排序字段 [ASC/DESC]  -- 必须:定义“前后”的排序规则

) AS 别名

LEAD(目标字段, 偏移量, 默认值) OVER (

    PARTITION BY 分组字段  -- 可选

    ORDER BY 排序字段 [ASC/DESC]  -- 必须

) AS 别名

参数说明

参数

作用

目标字段

要获取的“前/后行”的字段(如金额、日期、姓名等)

偏移量

可选,默认值为 1,表示“前 1 行”(LAG)或“后 1 行”(LEAD

默认值

可选,当“前/后行不存在”时返回的值(如第一行用 LAG(1) 会返回 NULL

PARTITION BY

可选,按指定字段分组,组内单独计算“前后行”(如按部门分组取员工数据)

ORDER BY

必须,定义组内数据的排序顺序,决定“前”和“后”的方向

二、典型应用场景(附示例)

假设存在表 sales,存储每日销售数据,结构如下:

date

product

amount

2024-01-01

A

100

2024-01-02

A

150

2024-01-03

A

200

2024-01-01

B

80

2024-01-02

B

120

场景 1:获取“上一行/下一行”数据(基础用法)

需求:查询每个产品的每日销售额,并显示“前一天销售额”和“后一天销售额”。

SELECT
    date,
    product,
    amount,
    -- 获取“同一产品”前 1 天的销售额,无则返回 0
    LAG(amount, 1, 0) OVER (
        PARTITION BY product  -- 按产品分组(不同产品不互相影响)
        ORDER BY date ASC     -- 按日期升序,“前”即“前一天”
    ) AS prev_day_amount,
    -- 获取“同一产品”后 1 天的销售额,无则返回 0
    LEAD(amount, 1, 0) OVER (
        PARTITION BY product
        ORDER BY date ASC     -- 按日期升序,“后”即“后一天”
    ) AS next_day_amount
FROM sales;

结果(清晰看到每行与前后行的关联):

date

product

amount

prev_day_amount

next_day_amount

2024-01-01

A

100

0

150

2024-01-02

A

150

100

200

2024-01-03

A

200

150

0

2024-01-01

B

80

0

120

2024-01-02

B

120

80

0

场景 2:计算“相邻行差值”(如日环比)

需求:按产品计算每日销售额的“环比增长额”(当日销售额 - 前一日销售额)。

SELECT
    date,
    product,
    amount,
    -- 当日金额 - 前一天金额 = 环比增长额
    amount - LAG(amount, 1, 0) OVER (
        PARTITION BY product
        ORDER BY date ASC
    ) AS day_on_day_growth
FROM sales;

结果

date

product

amount

day_on_day_growth

2024-01-01

A

100

100

2024-01-02

A

150

50

2024-01-03

A

200

50

2024-01-01

B

80

80

2024-01-02

B

120

40

场景 3:获取“间隔多行”的数据(自定义偏移量)

需求:查询每个产品的销售额,并显示“前 2 天”的销售额(偏移量设为 2)。

SELECT
    date,
    product,
    amount,
    -- 偏移量=2:取“前 2 天”的数据,无则返回 NULL
    LAG(amount, 2) OVER (
        PARTITION BY product
        ORDER BY date ASC
    ) AS prev_2day_amount
FROM sales;

结果(2024-01-03 的 A 产品,前 2 天是 2024-01-01 的 100):

date

product

amount

prev_2day_amount

2024-01-01

A

100

NULL

2024-01-02

A

150

NULL

2024-01-03

A

200

100

2024-01-01

B

80

NULL

2024-01-02

B

120

NULL

三、关键注意事项

ORDER BY 必须存在LAG/LEAD 依赖排序规则定义“前后”,缺少 ORDER BY 会报错或结果混乱。

PARTITION BY 分组隔离:无 PARTITION BY 时,全表视为一个“组”,跨行取值会跨越所有数据(如产品 A 和 B 的数据会互相取前后行)。

偏移量与默认值:偏移量必须为非负整数;默认值不指定时,“前后行不存在”会返回 NULL(可根据需求设为 0 或其他值)。

与自连接的区别:传统“跨行取值”需用自连接(如 a.date = b.date + 1),但 LAG/LEAD 代码更简洁、性能更高(尤其大数据量场景)。

总结

LAG() 和 LEAD() 是“跨行数据关联”的高效工具,核心用于:

计算环比、同比(相邻时间数据对比)

补全缺失的前后关联信息(如前/后订单、前/后员工数据)

简化复杂的行与行之间的逻辑对比

核心逻辑:按分组、定排序、取前后,即可灵活应对各类“跨行取值”需求。

到此这篇关于SQL中Lag()和LEAD()用法的文章就介绍到这了,更多相关SQL中Lag()和LEAD()用法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 一文解决连接MySQL报错is not allowed to connect to this MySQL server

    一文解决连接MySQL报错is not allowed to connect to this MySQL 

    这篇文章主要给大家介绍了关于如何通过一文解决连接MySQL报错is not allowed to connect to this MySQL server的相关资料,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2023-08-08
  • Mysql数据表分区技术PARTITION浅析

    Mysql数据表分区技术PARTITION浅析

    这篇文章主要介绍了Mysql数据表分区技术PARTITION浅析,分别介绍了 Mysql 中的分区技术 RANGE、LIST、 HASH,需要的朋友可以参考下
    2014-06-06
  • apache中访问不了伪静态页面的解决方法

    apache中访问不了伪静态页面的解决方法

    apache中访问不了伪静态页面的解决方法,有需要的朋友可以参考下
    2013-02-02
  • MySQL的锁机制及排查锁问题解析

    MySQL的锁机制及排查锁问题解析

    MySQL的锁机制包括行锁和表锁,行锁进一步细分为RecordLock、GapLock和Next-keyLock,行锁因其细粒度而减少冲突但开销大,可能引起死锁,本文介绍MySQL的锁机制及排查锁问题,感兴趣的朋友一起看看吧
    2025-01-01
  • MySQL事务保证数据一致性的核心讲解

    MySQL事务保证数据一致性的核心讲解

    这篇文章主要介绍了MySQL事务实现保证数据一致性的原理,事务不是万能药,它不能解决所有数据问题,比如硬件物理损坏需要靠备份恢复,但它是保障数据一致性的基础,没有事务,任何涉及多步操作的数据场景,都可能出现翻车风险,需要的朋友可以参考下
    2025-10-10
  • Mysql 直接查询存储的Json字符串中的数据

    Mysql 直接查询存储的Json字符串中的数据

    本文主要介绍了Mysql直接查询存储的Json字符串中的数据,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • ssm框架如何调用mysql存储过程

    ssm框架如何调用mysql存储过程

    这篇文章主要介绍了ssm框架如何调用mysql存储过程,首先是建表,创建存储过程,本文结合示例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
    2024-05-05
  • MySQL中多个left join on关联条件的顺序说明

    MySQL中多个left join on关联条件的顺序说明

    这篇文章主要介绍了MySQL中多个left join on关联条件的顺序说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • MySQL带你秒懂索引下推

    MySQL带你秒懂索引下推

    如果你在面试中,听到MySQL5.6”、“索引优化” 之类的词语,你就要立马get到,这个问的是“索引下推”。本文就来分分享这个小知识点索引下推
    2021-09-09
  • 完美转换MySQL的字符集 解决查看utf8源文件中的乱码问题

    完美转换MySQL的字符集 解决查看utf8源文件中的乱码问题

    本人转换过好多数据了,也用过了好多的办法,个人感觉最好用的就是使用MySQL命令导出导入中将字符集转换过去
    2011-11-11

最新评论