基于Table1分组选取最大绝对值记录并复制至Table2的SQL需求
嘿,我来帮你搞定这个SQL需求!你需要把Table1按Player_NAME分组,选出每组里Rating绝对值最大的记录,再把这些记录复制到Table2里。先明确下Table1的源数据:
源表Table1的数据
| Player_NAME | Player_NUMBER | Client_name | Client_country | Player_country | Rating |
|---|---|---|---|---|---|
| GERALD | A1234 | BENFIELD | IND | IND | 76 |
| GERALD | A6578 | ROTFIELD | USA | USA | 64 |
| KUMAR | P1234 | LFV | ARG | ARG | -24 |
| KUMAR | P5678 | JEURASIN | ARG | TUR | -32 |
| KUMAR | P0101 | ARGENIA | ARG | POL | -16 |
| ANDREW | R1234 | GENMAD | GER | GER | 23 |
下面是几种可行的解决方案:
方案1:使用窗口函数(推荐,适配MySQL 8+、PostgreSQL、SQL Server等支持窗口函数的数据库)
窗口函数是处理这类分组取最值场景最简洁的方式,我们可以用ROW_NUMBER()或者RANK()来标记每组内的排序:
INSERT INTO Table2 (Player_NAME, Player_NUMBER, Client_name, Client_country, Player_country, Rating) SELECT t.Player_NAME, t.Player_NUMBER, t.Client_name, t.Client_country, t.Player_country, t.Rating FROM ( SELECT *, -- 按玩家分组,每组内按Rating绝对值降序排名 ROW_NUMBER() OVER (PARTITION BY Player_NAME ORDER BY ABS(Rating) DESC) AS rank_num FROM Table1 ) t WHERE t.rank_num = 1;
- 解释:
PARTITION BY Player_NAME实现按玩家分组,ORDER BY ABS(Rating) DESC让每组中绝对值最大的记录排第一,ROW_NUMBER()给每条记录分配组内排名,最后筛选排名为1的记录插入到Table2。 - 注意:如果同一组内有多个记录的
Rating绝对值相同(比如两个记录绝对值都是76),ROW_NUMBER()只会随机选其中一条;如果想保留所有绝对值最大的记录,把ROW_NUMBER()换成RANK()即可。
方案2:使用子查询(适配不支持窗口函数的旧版数据库,如MySQL 5.x)
如果你的数据库不支持窗口函数,可以先通过子查询算出每组的最大Rating绝对值,再关联原表获取完整记录:
INSERT INTO Table2 (Player_NAME, Player_NUMBER, Client_name, Client_country, Player_country, Rating) SELECT t1.* FROM Table1 t1 INNER JOIN ( -- 先按玩家分组,算出每组的最大Rating绝对值 SELECT Player_NAME, MAX(ABS(Rating)) AS max_abs_rating FROM Table1 GROUP BY Player_NAME ) t2 ON t1.Player_NAME = t2.Player_NAME AND ABS(t1.Rating) = t2.max_abs_rating;
- 解释:子查询先得到每个玩家对应的最大
Rating绝对值,再通过INNER JOIN关联原表,找出所有符合条件的记录。这种方式会保留同一组内所有绝对值等于最大值的记录。
内容的提问来源于stack exchange,提问作者maheshkumarbm
相关产品推荐
相关产品推荐

