# 阿里云天池龙珠计划 SQL 训练营 - Task05 02

发布时间:2026/7/3 3:28:29
# 阿里云天池龙珠计划 SQL 训练营 - Task05 02 老铁们集合了今天继续“窗口函数”。上一期我们主要讲解了窗口函数的分组、排名两大功能。回顾请点击今天我们继续学习窗口函数的另外一个功能Lag函数我称之为“跨行取值”。6.1、lag函数解决的主要问题我们听新闻都会听到“70个大中城市商品住宅销售价格变动情况”环比上涨、下降多少同比上涨、下降多少。或者CPIPPI环比、同比的数据。更直观的听到同事、朋友说哪哪房价又涨了之前均价现在多少。这些数据是怎么计算出来的其实主要就是用lag()函数实现的。6.1、lag函数主要结构lag函数语句如下lag(字段10) over(partition by 分组字段 order by 排序字段).这里我讲一下“字段”是我要查看的数据内容。比如我想在同一行内显示本月房价和上个月房价那这个字段就是“房价”“1”就是我要偏移的行数。比如我有本月数据我打算看上个月数据那这个行数就是1一般表格一行为一个月如果我要看去年这个月的数据那就是“12”就是偏移12行取去年同期数据。“0”没有数据的话默认为0.好比我有“上海**小区25年月度房价表”。如下我想在本月的这一行显示上一个月的均价便于对比。希望表格就为我们看到由于我们以年为一个周期那第一个月这一行就没有上一个月的数据那应该取什么我们写“0”这一行就写0.如果我们不写0就是没有这个字段MySQL会用null填充。但我还是建议写0比如我写lag(本月均价元/平米,1,0),那房价表格如下“partition by 分组字段”就是我取值的范围好比上面的表格就是按照年来分组的。假如这个表有25年和26年的月度均价表。lag(字段10) over(partition by 年表格如下我们重点看26年1月份的表格是0因为统计的区间是年“分组字段 order by 排序字段”这个就是排列的顺序上表我们是按照月份排序的那么排序字段就是“月份”那么整个语句完整地写出来就是lag(本月均价元/平米10) over(partition by 年份 order by 月份)。6.2、实际应用如果大家上面内容都看明白了我们现在结合mysql语句具体表格来应用。表格如下-- 1. 建表CREATETABLEshop_month_sales(idINTPRIMARYKEYAUTO_INCREMENT,shop_idINTCOMMENT商家ID,stat_monthVARCHAR(7)COMMENT统计月份,sales_amountDECIMAL(10,2)COMMENT月度销售额);-- 2. 插入测试数据2个商家各6个月数据INSERTINTOshop_month_sales(shop_id,stat_month,sales_amount)VALUES(1001,2026-01,12000.00),(1001,2026-02,15000.00),(1001,2026-03,13500.00),(1001,2026-04,18000.00),(1001,2026-05,22000.00),(1001,2026-06,20000.00),(1002,2026-01,8000.00),(1002,2026-02,9500.00),(1002,2026-03,11000.00),(1002,2026-04,10500.00),(1002,2026-05,13000.00),(1002,2026-06,14500.00); 1基础用法取每个商家「上个月的销售额」每一行后面通常是本月销售额跟上一个月地销售额偏移量默认1.SELECTshop_id,stat_month,sales_amountAS本月销售额,LAG(sales_amount)OVER(PARTITIONBYshop_idORDERBYstat_month)AS上月销售额FROMshop_month_sales;运行结果shop_id |stat_month |本月销售额 |上月销售额1001 |2026-01 |12000.00 |NULL1001 |2026-02 |15000.00 |12000.001001 |2026-03 |13500.00 |15000.001001 |2026-04 |18000.00 |13500.001001 |2026-05 |22000.00 |18000.001001 |2026-06 |20000.00 |22000.001002 |2026-01 |8000.00 |NULL1002 |2026-02 |9500.00 |8000.001002 |2026-03 |11000.00 |9500.001002 |2026-04 |10500.00 |11000.001002 |2026-05 |13000.00 |10500.001002 |2026-06 |14500.00 |13000.00每个商家地第一行没有数据默认返回null 2指定偏移量取「上上个月的销售额」偏移量为2就可以向上两行对应上上个月地数据SELECTshop_id,stat_month,sales_amountAS本月销售额,LAG(sales_amount,2)OVER(PARTITIONBYshop_idORDERBYstat_month)AS上上月销售额FROMshop_month_sales;运行结果1月、2月都会返回null从3月开始取第一个月地数据以此类推。 3设置默认值消除null用0代替第三个参数设置为0。当第一行取不到值得时候返回0。SELECTshop_id,stat_month,sales_amountAS本月销售额,LAG(sales_amount,1,0)OVER(PARTITIONBYshop_idORDERBYstat_month)AS上月销售额FROMshop_month_sales;运行后null会为0。运行结果shop_id |stat_month |本月销售额 |上月销售额1001 |2026-01 |12000.00 |01001 |2026-02 |15000.00 |12000.001001 |2026-03 |13500.00 |15000.001001 |2026-04 |18000.00 |13500.001001 |2026-05 |22000.00 |18000.001001 |2026-06 |20000.00 |22000.001002 |2026-01 |8000.00 |01002 |2026-02 |9500.00 |8000.001002 |2026-03 |11000.00 |9500.001002 |2026-04 |10500.00 |11000.001002 |2026-05 |13000.00 |10500.001002 |2026-06 |14500.00 |13000.00 4业务实战计算月度环比增长率这个是lag函数最常用的地方。月度环比增长率本月-上月/上月*100%。SELECTshop_id,stat_month,sales_amountAS本月销售额,LAG(sales_amount)OVER(PARTITIONBYshop_idORDERBYstat_month)AS上月销售额,ROUND((sales_amount-LAG(sales_amount)OVER(PARTITIONBYshop_idORDERBYstat_month))/LAG(sales_amount)OVER(PARTITIONBYshop_idORDERBYstat_month)*100,2)AS环比增长率FROMshop_month_sales;结果如下shop_id |stat_month |本月销售额 上月销售额 环比增长率 (%)1001 |2026-01 |12000.00 |NULL |NULL1001 |2026-02 |15000.00 |12000.00 |25.001001 |2026-03 |13500.00 |15000.00 |-10.001001 |2026-04 |18000.00 |13500.00 |33.331001 |2026-05 |22000.00 |18000.00 |22.221001 |2026-06 |20000.00 |22000.00 |-9.091002 |2026-01 |8000.00 |NULL |NULL1002 |2026-02 |9500.00 |8000.00 |18.751002 |2026-03 |11000.00 |9500.00 |15.791002 |2026-04 |10500.00 |11000.00 |-4.551002 |2026-05 |13000.00 |10500.00 |23.811002 |2026-06 |14500.00 |13000.00 |11.54结果如上。如果说我们的数据在多一点有两年24个月的数据我们的航偏移量就可以是12这样就可以计算同比数据。6.3、使用注意事项6.3.1 必须有排序字段即order by。我们的例子是用月份来排序的。如果不使用order by,那么mysql就不知道上一行的数据在哪里就会随机取值结果不可控6.3.2 加了partition by后每一个分组内都是从对应的第一行开始取值。我们的例子是按照shop id取值的所以每一个shop id的第一行都是null。6.3.3 窗口函数不会压缩结果的行数原始表格有多少行查询结果就有多少行这个是跟group by不同的地方。6.4、延申配套的lead函数和lag对应的函数就是lead函数lag函数是向上取值lead函数是向下取值用法完全一样。向上取值是统计过去向下取值就是用来进行预测。6.5、你的课后作业基于表“shop_month_sales”。题目 1LEAD 基础取数查询所有商家的月度销售数据新增一列 下月销售额使用 LEAD() 获取同商家下一个月的销售额。题目 2设置默认值查询所有商家的月度销售数据使用 LAG() 获取上月销售额要求首月的上月销售额显示为 0而非 NULL。题目 3指定偏移行数查询所有商家的月度销售数据新增一列 上上月销售额向前偏移 2 行获取对应数据。题目 4计算月度环比差值计算每个商家每月销售额与上月的绝对差值本月销售额 - 上月销售额结果列命名为 月度差额。题目 5筛选环比下跌月份筛选出销售额环比下降的所有月份输出商家 ID、统计月份、本月销售额、上月销售额、环比增长率保留 2 位小数。题目 6向后偏移 2 行使用 LEAD() 函数新增一列 下下月销售额获取同商家往后第 2 个月的销售额。题目 7增长标记对每个商家的每个月做标记当月销售额 上月销售额标记为 1增长当月销售额 ≤ 上月销售额标记为 0下跌 / 持平每个商家的首月1 月统一标记为 0结果列命名为 is_growth。题目 8累计周期涨幅计算利用偏移函数计算每个商家 6 月销售额相比 1 月的整体涨幅比例保留 2 位小数。公式(6 月销售额 - 1 月销售额) / 1 月销售额 * 100%答案我会放在评论区置顶写完自己对照。