SQL中Lag()和LEAD()的用法示例詳解
前言
LAG() 和 LEAD() 是 SQL 中常用的窗口函數(shù),核心作用是在同一結(jié)果集中,根據(jù)指定排序規(guī)則,獲取當(dāng)前行“前面”或“后面”某行的數(shù)據(jù),無需進行自連接,極大簡化了“跨行取值”的邏輯。
一、核心定義與語法
兩者語法結(jié)構(gòu)完全一致,僅功能相反(LAG 取前,LEAD 取后)。
基本語法
LAG(目標字段, 偏移量, 默認值) OVER (
PARTITION BY 分組字段 -- 可選:按某字段分組,組內(nèi)獨立計算
ORDER BY 排序字段 [ASC/DESC] -- 必須:定義“前后”的排序規(guī)則
) AS 別名
LEAD(目標字段, 偏移量, 默認值) OVER (
PARTITION BY 分組字段 -- 可選
ORDER BY 排序字段 [ASC/DESC] -- 必須
) AS 別名
參數(shù)說明
參數(shù) | 作用 |
目標字段 | 要獲取的“前/后行”的字段(如金額、日期、姓名等) |
偏移量 | 可選,默認值為 1,表示“前 1 行”(LAG)或“后 1 行”(LEAD) |
默認值 | 可選,當(dāng)“前/后行不存在”時返回的值(如第一行用 LAG(1) 會返回 NULL) |
PARTITION BY | 可選,按指定字段分組,組內(nèi)單獨計算“前后行”(如按部門分組取員工數(shù)據(jù)) |
ORDER BY | 必須,定義組內(nèi)數(shù)據(jù)的排序順序,決定“前”和“后”的方向 |
二、典型應(yīng)用場景(附示例)
假設(shè)存在表 sales,存儲每日銷售數(shù)據(jù),結(jié)構(gòu)如下:
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:獲取“上一行/下一行”數(shù)據(jù)(基礎(chǔ)用法)
需求:查詢每個產(chǎn)品的每日銷售額,并顯示“前一天銷售額”和“后一天銷售額”。
SELECT
date,
product,
amount,
-- 獲取“同一產(chǎn)品”前 1 天的銷售額,無則返回 0
LAG(amount, 1, 0) OVER (
PARTITION BY product -- 按產(chǎn)品分組(不同產(chǎn)品不互相影響)
ORDER BY date ASC -- 按日期升序,“前”即“前一天”
) AS prev_day_amount,
-- 獲取“同一產(chǎn)品”后 1 天的銷售額,無則返回 0
LEAD(amount, 1, 0) OVER (
PARTITION BY product
ORDER BY date ASC -- 按日期升序,“后”即“后一天”
) AS next_day_amount
FROM sales;結(jié)果(清晰看到每行與前后行的關(guān)聯(lián)):
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:計算“相鄰行差值”(如日環(huán)比)
需求:按產(chǎn)品計算每日銷售額的“環(huán)比增長額”(當(dāng)日銷售額 - 前一日銷售額)。
SELECT
date,
product,
amount,
-- 當(dāng)日金額 - 前一天金額 = 環(huán)比增長額
amount - LAG(amount, 1, 0) OVER (
PARTITION BY product
ORDER BY date ASC
) AS day_on_day_growth
FROM sales;結(jié)果:
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:獲取“間隔多行”的數(shù)據(jù)(自定義偏移量)
需求:查詢每個產(chǎn)品的銷售額,并顯示“前 2 天”的銷售額(偏移量設(shè)為 2)。
SELECT
date,
product,
amount,
-- 偏移量=2:取“前 2 天”的數(shù)據(jù),無則返回 NULL
LAG(amount, 2) OVER (
PARTITION BY product
ORDER BY date ASC
) AS prev_2day_amount
FROM sales;結(jié)果(2024-01-03 的 A 產(chǎn)品,前 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 |
三、關(guān)鍵注意事項
ORDER BY 必須存在:LAG/LEAD 依賴排序規(guī)則定義“前后”,缺少 ORDER BY 會報錯或結(jié)果混亂。
PARTITION BY 分組隔離:無 PARTITION BY 時,全表視為一個“組”,跨行取值會跨越所有數(shù)據(jù)(如產(chǎn)品 A 和 B 的數(shù)據(jù)會互相取前后行)。
偏移量與默認值:偏移量必須為非負整數(shù);默認值不指定時,“前后行不存在”會返回 NULL(可根據(jù)需求設(shè)為 0 或其他值)。
與自連接的區(qū)別:傳統(tǒng)“跨行取值”需用自連接(如 a.date = b.date + 1),但 LAG/LEAD 代碼更簡潔、性能更高(尤其大數(shù)據(jù)量場景)。
總結(jié)
LAG() 和 LEAD() 是“跨行數(shù)據(jù)關(guān)聯(lián)”的高效工具,核心用于:
計算環(huán)比、同比(相鄰時間數(shù)據(jù)對比)
補全缺失的前后關(guān)聯(lián)信息(如前/后訂單、前/后員工數(shù)據(jù))
簡化復(fù)雜的行與行之間的邏輯對比
核心邏輯:按分組、定排序、取前后,即可靈活應(yīng)對各類“跨行取值”需求。
到此這篇關(guān)于SQL中Lag()和LEAD()用法的文章就介紹到這了,更多相關(guān)SQL中Lag()和LEAD()用法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
從MySQL的源碼剖析Innodb buffer的命中率計算
這篇文章主要介紹了從MySQL的源碼剖析Innodb buffer的命中率計算,作者結(jié)合C語言寫的算法來分析innodb buffer hit Ratios,需要的朋友可以參考下2015-05-05
MySQL數(shù)據(jù)查看SELECT條件大于?小于(小白入門篇)
這篇文章主要為大家介紹了MySQL數(shù)據(jù)查看SELECT條件大于和小于的語句學(xué)習(xí),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-05-05
mysql 連接出現(xiàn)Public Key Retrieval is n
在MySQL連接中出現(xiàn)“Public Key Retrieval is not allowed”錯誤,通常是因為在使用安全套接字層(SSL)連接時遇到了問題,本文就來介紹一下解決方法,感興趣的可以了解一下2024-03-03

