SQL中实现第n列后每两列一组转置为行的解决方案问询
宽表按每2列分组转置长表解决方案
核心实现逻辑
- 先确定固定维度列:第1~n列为固定保留列(示例场景中n=1,固定列仅为
Player ID) - 将第n+1列及之后的列按顺序每2个划分为一组,若总列数为奇数,最后一个单独列可按需丢弃或补空值后分组
- 每组对应生成一行新数据,行结构为:
[固定列值] + [本组第1列列名, 本组第2列列名, 本组第1列值, 本组第2列值]
示例场景验证
对应你提到的玩家对阵得分场景,原表结构参考:
| Player ID | Team 1 | Team 2 | Team 3 | Team 4 |
|---|---|---|---|---|
| 1001 | 89 | 92 | 78 | 85 |
| 1002 | 76 | 81 | 93 | 88 |
转置后输出的目标结构:
| Player ID | Teams 1 | Teams 2 | Score 1 | Score 2 |
|---|---|---|---|---|
| 1001 | Team 1 | Team 2 | 89 | 92 |
| 1001 | Team 3 | Team 4 | 78 | 85 |
| 1002 | Team 1 | Team 2 | 76 | 81 |
| 1002 | Team 3 | Team 4 | 93 | 88 |
常用工具实现代码
Python(Pandas,通用版本)
import pandas as pd # 1. 读取源数据 df = pd.read_excel("你的源数据文件路径.xlsx") # 2. 自定义n值:第n列之前为固定维度列 n = 1 fix_cols = df.columns[:n].tolist() group_cols = df.columns[n:].tolist() result_list = [] # 3. 按步长2遍历分组列 for i in range(0, len(group_cols), 2): # 不足2列时跳过最后一个单独列 if i + 1 >= len(group_cols): break col1, col2 = group_cols[i], group_cols[i+1] temp_df = df[fix_cols + [col1, col2]].copy() # 重命名列并补充对阵队伍名称 temp_df.columns = fix_cols + ["Score 1", "Score 2"] temp_df["Teams 1"] = col1 temp_df["Teams 2"] = col2 # 调整列顺序匹配输出要求 temp_df = temp_df[fix_cols + ["Teams 1", "Teams 2", "Score 1", "Score 2"]] result_list.append(temp_df) # 4. 合并所有分组结果 final_df = pd.concat(result_list, ignore_index=True)
SQL(以MySQL为例,源表名为player_score)
SELECT `Player ID`, 'Team 1' AS `Teams 1`, 'Team 2' AS `Teams 2`, `Team 1` AS `Score 1`, `Team 2` AS `Score 2` FROM player_score UNION ALL SELECT `Player ID`, 'Team 3' AS `Teams 1`, 'Team 4' AS `Teams 2`, `Team 3` AS `Score 1`, `Team 4` AS `Score 2` FROM player_score -- 有更多对阵分组时,继续追加对应UNION ALL查询块即可 ORDER BY `Player ID`;
内容的提问来源于stack exchange,提问作者Tashil Moorateeah
相关产品推荐
相关产品推荐

