--最簡單的寫法
--分群的時候依照 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_id
grass_date
previous_orders
current_orders
next_orders
37137599
2022/3/1
3267
4277
37137599
2022/3/2
3267
4277
9239
37137599
2022/3/3
4277
9239
2254
進階寫法 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_id
grass_date
previous_orders
current_orders
difference
growth
37137599
2022/3/1
3267
37137599
2022/3/2
3267
4277
1010
31%
37137599
2022/3/3
4277
9239
4962
116%
37137599
2022/3/4
9239
2254
-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
Pingback: [數據分析#0] 數據分析文章導覽 - Lisa Wu 財富自由之路