如何使用LAG函数实现多组行的整组奖金下移
问题背景
现有如下输入数据:
| player_id | team_ranking | price_money |
|---|---|---|
| 131 | 9 | 100 |
| 289 | 9 | 100 |
| 83 | 9 | 100 |
| 236 | 8 | 200 |
| 154 | 8 | 200 |
| 230 | 7 | 300 |
| 72 | 7 | 300 |
| 200 | 6 | 400 |
| 174 | 6 | 400 |
| 326 | 6 | 400 |
| 261 | 6 | 400 |
| 60 | 5 | 500 |
| 181 | 5 | 500 |
| 387 | 5 | 500 |
| 34 | 4 | 600 |
| 144 | 4 | 600 |
| 377 | 3 | 700 |
| 222 | 3 | 700 |
| 112 | 3 | 700 |
| 16 | 2 | 800 |
| 36 | 2 | 800 |
| 299 | 1 | 1000 |
期望得到的输出为:
| player_id | team_ranking | price_money |
|---|---|---|
| 131 | 9 | 0 |
| 289 | 9 | 0 |
| 83 | 9 | 0 |
| 236 | 8 | 100 |
| 154 | 8 | 100 |
| 230 | 7 | 200 |
| 72 | 7 | 200 |
| 200 | 6 | 300 |
| 174 | 6 | 300 |
| 326 | 6 | 300 |
| 261 | 6 | 300 |
| 60 | 5 | 400 |
| 181 | 5 | 400 |
| 387 | 5 | 400 |
| 34 | 4 | 500 |
| 144 | 4 | 500 |
| 377 | 3 | 600 |
| 222 | 3 | 600 |
| 112 | 3 | 600 |
| 16 | 2 | 700 |
| 36 | 2 | 700 |
| 299 | 1 | 800 |
问题描述
我希望将每个team_ranking组的price_money整体下移一个等级,但执行以下代码后,仅实现了单行price_money下移,而非整组下移:
SELECT Player_id, Team_Ranking, LAG(Price_Money, 1, 0) OVER (ORDER BY Team_Ranking desc) AS Price_Money FROM table;
得到的错误输出如下:
| Player_id | Team_Ranking | Price_Money |
|---|---|---|
| 289 | 9 | 0 |
| 83 | 9 | 100 |
| 131 | 9 | 100 |
| 236 | 8 | 100 |
| 154 | 8 | 200 |
| 230 | 7 | 200 |
| 72 | 7 | 300 |
| 200 | 6 | 300 |
| 174 | 6 | 400 |
| 326 | 6 | 400 |
| 261 | 6 | 400 |
| 60 | 5 | 400 |
| 387 | 5 | 500 |
| 181 | 5 | 500 |
| 34 | 4 | 500 |
| 144 | 4 | 600 |
| 377 | 3 | 600 |
| 222 | 3 | 700 |
| 112 | 3 | 700 |
| 16 | 2 | 700 |
| 36 | 2 | 800 |
| 299 | 1 | 800 |
请问如何正确实现整组price_money下移的需求?
解决方案
原SQL仅对单行数据应用LAG函数,未按组处理价格。要实现整组下移,需先获取每个team_ranking对应的基准价格,再对基准值按等级排序后使用LAG,最后将处理后的价格关联回原表。
方法一:子查询获取组基准值并关联
WITH rank_prices AS ( SELECT team_ranking, price_money, LAG(price_money, 1, 0) OVER (ORDER BY team_ranking DESC) AS new_price FROM ( -- 去重获取每个等级对应的唯一price_money SELECT DISTINCT team_ranking, price_money FROM your_table ) t ) SELECT p.player_id, p.team_ranking, rp.new_price AS price_money FROM your_table p JOIN rank_prices rp ON p.team_ranking = rp.team_ranking ORDER BY p.team_ranking DESC, p.player_id;
方法二:窗口函数嵌套实现组级LAG
如果每个team_ranking的price_money值完全一致,可直接用FIRST_VALUE获取组内价格,再对组级价格应用LAG:
SELECT player_id, team_ranking, LAG(FIRST_VALUE(price_money) OVER (PARTITION BY team_ranking), 1, 0) OVER (ORDER BY team_ranking DESC) AS price_money FROM your_table ORDER BY team_ranking DESC, player_id;
说明
- 两种方法核心都是先按
team_ranking分组处理价格,再将结果批量应用到该组所有行,而非逐行移动。 - 方法一通用性更强,适用于所有场景;方法二代码更简洁,但依赖同一等级价格一致的前提(符合当前输入数据的特征)。
内容的提问来源于stack exchange,提问作者Zhenyu He
相关产品推荐
相关产品推荐

