[數據分析#29] SQL LEAD() LAG() 函數怎麼寫?5 種用法教學

LEAD & LAG 可以說是視窗函數 (Window Function) 裡面,最好用的前幾名!這篇會跟大家分享,LEAD & LAG 要用在哪?

  • 分享我在電商數據分析,最常用到的 2 個情境

LEAD & LAG 怎麼寫?

  • 我會分享 5 種寫法,從簡單到進階
  • 分享我的資料集跟練習題

LEAD & LAG 函數是什麼?

視窗函數 (Window Function) 是什麼?

  • LEAD & LAG 是 視窗函數 (Window Function) 的一種,SQL 函數主要分成 3 種:普通函數、聚合函數、視窗函數 3 種
    • 普通函數、聚合函數比較好理解,視窗函數稍微困難一點,不過在做分群分析的時候,是很好用的函數
    • 視窗函數 (Window Function) 簡單來說,他可以針對一個資料集做分割,再對分割後的資料做計算或是其他處理。例如:A 表中有 Lisa 的財務資料,財務資料中可以分成:吃、喝、玩、樂 4 種資料,Window Function 可以透過一段語法,就將吃、喝、玩、樂 4 種資料分割,再將吃的資料做排序或是再用聚合函數做計算
      • 視窗函數由 2 個主要函數組成:分割作用的 PARTITION BY 以及排序作用的 ORDER BY

LEAD & LAG 函數的作用是什麼?

  • LEAD & LAG 函數會以使用者填入的 PARTITION BY 和 ORDER BY 進行分割跟排序
    • LAG 函數,例如 LAG(order),就會利用 PARTITION BY 和 ORDER BY 進行分割跟排序後,排列好的資料集,列出前一筆 order 的數量
    • LEAD 函數,例如 LAG(order),就會利用 PARTITION BY 和 ORDER BY 進行分割跟排序後,排列好的資料集,列出後一筆 order 的數量
SQL LEAD LAG 教學 怎麼用
SQL LEAD & LAG 的基本解釋

PARTITION BY 和 ORDER BY 要做什麼?差別為何?

  • PARTITION BY 用來分群,如果 PARTITION BY shop_id,就是把店家分成一群一群
  • ORDER BY 用來排序,如果 PARTITION BY shop_id,然後 ORDER BY date,就是把店家分成一群一群,再以 date 排序
  • 最後面會在進階寫法 4 說明這兩者的不同
    • PARTITION BY shop_id ORDER BY date
    • ORDER BY shop_id, date
    • 如果可以懂這兩個的不同,接下來所有視窗函數 (Window Function) 都難不倒了!
SQL PARTITION BY & ORDER BY 差別教學
用 PARTITION BY, ORDER BY 跟只用 ORDER BY 的差別

什麼情境下會使用 LEAD & LAG 函數?

在處理電商的資料,以下幾個情境,都非常適合使用 LEAD & LAG 函數

  • 前後時段的表現對比:算某一間店前後兩段時間的表現
    • 舉例:Lisa 咖啡店,我們已經算出1月、2月、3月的業績,我們可以用 LAG 函數取出這間店前一段時間的表現 (1月),用 LEAD 函數取出這間店後一段時間的表現 (2月),再列出現在這段時間的表現,就可以在 SQL 中就差異的處理 (Difference)
店家 (shop_id)日期 (date)業績
Lisa 咖啡店1月50萬
Lisa 咖啡店2月100萬
Lisa 咖啡店3月200萬
資料表
店家 (shop_id)日期 (date)現在業績 (current)前一段時間業績 (previous)後一段時間業績 (next)差異 (Difference)
Lisa 咖啡店2月100萬50萬200萬100萬-50萬
使用 LEAD LAG 後可以知道業績差異
  • 計算用戶頻次:在計算用戶頻次的時候,可以用 LEAD & LAG 函數帶出每個用戶上一次跟下一次的購買時間有多長
    • 舉例:Lisa 在 Lisa 咖啡店的消費情況
    • 最後,再算出 Lisa 的平均間隔天數就可以了,就會是 Lisa 平均 (31+16)/2=23.5,Lisa 平均 23.5 會去 Lisa 咖啡店消費一次
用戶 (user_id)消費日期 (date)
Lisa2022/1/1
Lisa2022/1/31
Lisa2022/2/15
Lisa 消費日期
用戶 (user_id)消費日期 (date)前一次消費日期 (date)間隔天數
Lisa2022/1/1nullnull
Lisa2022/1/312022/1/131
Lisa2022/2/152022/1/3116
使用 LEAD LAG 後可以知道用戶購買頻次

LEAD & LAG 函數怎麼寫?5 種好用的寫法舉例

範例資料集介紹:Sales

  • Sales 這份資料集很簡單,只包含店家編號 (shop_id)、日期 (grass_date)、銷售訂單數量 (orders)
shop_idgrass_dateorders

最簡單的寫法:LEAD & LAG

  • 取出某一天、前一天、後一天的訂單資料
  • 用 LAG,ORDER BY 日期,可以取出前一天的訂單
  • 用 LEAD,ORDER BY 日期,可以取出後一天的訂單
--最簡單的寫法
--分群的時候依照 grass_date, 依照日期帶出,前一次與下一次的業績
SELECT grass_date
, orders AS current_orders
, lag(orders) OVER (ORDER BY grass_date) AS previous_orders
, lead(orders) OVER (ORDER BY grass_date) AS next_orders
FROM sales

進階寫法 1:LEAD & LAG,ORDER BY 兩個條件以上

  • 取出每一個店家 (先分一次群)、某一天、前一天、後一天 (再以日期做排序) 的訂單資料
  • 用 LAG,ORDER BY 店家、日期,可以取出前一天的訂單
  • 用 LEAD,ORDER BY 店家、日期,可以取出後一天的訂單
--進階寫法 1
--LEAD & LAG
--分群的時候依照 shop_id, grass_date 帶出,前一次與下一次的業績
SELECT shop_id
, grass_date
, lag(orders) OVER (ORDER BY shop_id, grass_date) AS previous_orders
, orders AS current_orders
, lead(orders) OVER (ORDER BY shop_id, grass_date) AS next_orders
FROM sales
店家編號日期前一天的訂單今天的訂單隔一天的訂單
shop_idgrass_dateprevious_orderscurrent_ordersnext_orders
371375992022/3/132674277
371375992022/3/2326742779239
371375992022/3/3427792392254

進階寫法 2:LEAD & LAG,ORDER BY 兩個條件後比對

  • 取出每一個店家 (先分一次群)、某一天、前一天、後一天 (再以日期做排序) 的訂單資料
  • 用 LAG,ORDER BY 店家、日期,可以取出前一天的訂單
  • 用 LEAD,ORDER BY 店家、日期,可以取出後一天的訂單
  • 計算每一個店家的成長狀況,拿某一天除以前一天的業績
--進階寫法 2
--LEAD & LAG
--分群的時候依照 shop_id, grass_date 帶出,前一次與下一次的業績
--最後再算出前後差 (difference) 以及 成長率 (growth)
SELECT shop_id
, grass_date
, LAG(orders) OVER (ORDER BY shop_id, grass_date) AS previous_orders
, orders AS current_orders
, orders - LAG(orders) OVER (ORDER BY shop_id, grass_date) AS difference
, (orders / LAG(orders) OVER (ORDER BY shop_id, grass_date)) -1 AS growth
FROM sales
shop_idgrass_dateprevious_orderscurrent_ordersdifferencegrowth
371375992022/3/13267
371375992022/3/232674277101031%
371375992022/3/3427792394962116%
371375992022/3/492392254-6985-76%

進階寫法 3:LEAD & LAG,先分群 (CASE WHEN) 後再 ORDER BY 兩個條件

  • 取出每一個店家、每一個月的業績分群
  • 用 LAG,ORDER BY 店家、日期,可以取出前一天的業績分群
  • 用 LEAD,ORDER BY 店家、日期,可以取出後一天的業績分群
--進階寫法 3
--LEAD & LAG & CASE WHEN
--子查詢裡面先算出這間店這個日期的訂單區間 (order_tier)
--最後再用 LEAD & LAG 列出這間店前後的訂單區間 (order_tier) 變化
SELECT shop_id
, grass_month
, order_tier AS current_order_tier
, lag(order_tier) OVER (ORDER BY shop_id, grass_month) AS previous_order_tier
FROM (
    SELECT shop_id
    , grass_month
    , CASE WHEN orders < 10 THEN 'order<1000'
            WHEN orders >= 10 THEN 'order>1000' ELSE 'no_order' END AS order_tier
    FROM sales
)

進階寫法 4:LEAD & LAG,PARTITION BY & ORDER BY 同時使用

  • 下面兩段 SQL Query 的結果是一樣的,但是 SQL 在處理資料的時候使用 LEAD & LAG 的時候
  • 只用 ORDER BY:不會先分群,直接排序
  • 用 PARTITION BY & ORDER BY:先以 PARTITION BY 的指定欄位分群,在分群內以 ORDER BY 排序
--LEAD & LAG (只用 ORDER BY)
--進階寫法 2
SELECT shop_id
, grass_date
, LAG(orders) OVER (ORDER BY shop_id, grass_date) AS previous_orders
, orders AS current_orders
FROM sales
--LEAD & LAG (PARTITION BY & ORDER BY)
SELECT shop_id
, grass_date
, LAG(orders) OVER (PARTITION BY shop_id ORDER BY grass_date) AS previous_orders
, orders AS current_orders
, orders - LAG(orders) OVER (PARTITION BY shop_id ORDER BY grass_date) AS difference
FROM sales

如何練習 LEAD & LAG 函數?

  1. 使用 Google BigQuery 沙盒功能
  2. 匯入資料集,之前有寫過一篇教學,如果不會的話可以看這裡:Google BigQuery 教學:3 分鐘完成資料匯入跟 SQL 查詢
  3. 練習上面的所有寫法,有寫過跟看過,理解到的是不同高度!

更多學習資源推薦

網路上的 SQL 學習資源很多,這裡會推薦我有使用過的 SQL 學習資源:

如何使用這個網站?我的數據分析文章導覽!裡面也會分享更多實用 SQL 教學:

【1 對 1 免費諮詢】數據分析師 0~1 培訓班陪你一路到轉職成功!

hi 我是 Lisa

你也是 0 經驗、沒有相關背景,但也想要轉職數據分析師,或運用數據分析,提升在領域的專業度嗎?

-

你是否也覺得,數據分析的網路學習資源很多,但是多到不知道從哪裡開始?

學了很多工具,但學完了,問題才真正開始,不知道業界怎麼使用?又該如何面臨工作跟面試?

-

我在 2019 年從營運專員的職位轉職到數據分析師

在這之後,因為數據分析,也讓我快速建構不同領域的知識:行銷、營運、商業策略、產品、網頁

轉職過程中,花了很多時間成本摸索

我發現,學數據分析最快的方式是:

  1. 確認自己跟市場需求之間的差距:訂定轉職策略及了解數據分析師的工作方式
  2. 以業界應用的角度學習工具:包括數據工具及分析用思維架構,並且如何高效運用
  3. 建立一個商業上的真實專案,並且得到回饋:打造屬於你及貼合職缺需求的作品集和專案
  4. 打造一個高效履歷跟面談:透過高價值包裝術拿下面試、成功獲得數據行業的門票

當初如果我有這套系統思維,應該可以在短時間內轉職,馬上拿到進入業界的門票

-

現在,我想把這套完整課程分享給你

這是專門為了 0 經驗、沒有相關背景的轉職者所設計

不需要去考研究所、不需要花大錢準備出國讀書

可以用最快的時間準備轉職、拿到門票!

-

如果你正在準備轉職數據分析師,且試圖找過解決辦法卻始終治標不治本!歡迎跟我預約免費 1 對 1 諮詢,我會在諮詢時,了解你的需求並且評估我是否可以協助到你!

電子書 職場人必學的數據分析術

Lisa Wu

Hi 大家好!我是喜歡探索身心靈健康及平衡的數據分析師 Lisa Wu!這個網站會幫助你:利用數據分析 (理性) 及 身心靈平衡 (感性) 的系統,去達成人生目標!如果你對我的人生系統工具有興趣,歡迎聯繫我:couplehonest@gmail.com

This Post Has One Comment

Comments are closed.