You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL Server中Pivoting行转列:多行转单行列展示问题咨询

解决多行同ReferenceID转单行多列的问题

我懂你为啥常规PIVOT搞不定了——普通透视一般是针对单个字段的聚合转列,而你要把同一ReferenceID下的多条记录,按顺序拆成带序号的多组字段(Field1_1、Field2_1,Field1_2、Field2_2...),这得先给每行加个序号,再用条件聚合来实现,下面给你两种实用方案:

方法1:手动指定列数(适合固定行数的场景)

如果你的数据里每个ReferenceID最多只有3行,直接用窗口函数ROW_NUMBER()给行编号,再通过条件聚合转列就行:

WITH NumberedRows AS (
    SELECT 
        ReferenceID,
        Field1,
        Field2,
        Field3,
        -- 按你需要的排序逻辑调整ORDER BY,这里用SELECT NULL只是占位
        ROW_NUMBER() OVER (PARTITION BY ReferenceID ORDER BY (SELECT NULL)) AS RowNum
    FROM YourTableName
)
SELECT
    ReferenceID,
    MAX(CASE WHEN RowNum = 1 THEN Field1 END) AS Field1_1,
    MAX(CASE WHEN RowNum = 1 THEN Field2 END) AS Field2_1,
    MAX(CASE WHEN RowNum = 1 THEN Field3 END) AS Field3_1,
    MAX(CASE WHEN RowNum = 2 THEN Field1 END) AS Field1_2,
    MAX(CASE WHEN RowNum = 2 THEN Field2 END) AS Field2_2,
    MAX(CASE WHEN RowNum = 2 THEN Field3 END) AS Field3_2,
    MAX(CASE WHEN RowNum = 3 THEN Field1 END) AS Field1_3,
    MAX(CASE WHEN RowNum = 3 THEN Field2 END) AS Field2_3,
    MAX(CASE WHEN RowNum = 3 THEN Field3 END) AS Field3_3
FROM NumberedRows
GROUP BY ReferenceID;

要是你有特定的行顺序要求(比如按Field1排序),把ORDER BY (SELECT NULL)换成实际的列就行。

方法2:动态SQL(适配任意行数的场景)

如果每个ReferenceID的行数不固定,手动写列太麻烦,用动态SQL自动生成所有需要的列:

DECLARE @Columns NVARCHAR(MAX), @SQL NVARCHAR(MAX);

-- 先算出每个ReferenceID最多有多少行
WITH MaxRows AS (
    SELECT MAX(RowNum) AS MaxRowCount
    FROM (
        SELECT ROW_NUMBER() OVER (PARTITION BY ReferenceID ORDER BY (SELECT NULL)) AS RowNum
        FROM YourTableName
    ) t
),
-- 生成1到最大行数的序列(兼容SQL Server全版本)
RowNums AS (
    SELECT TOP (SELECT MaxRowCount FROM MaxRows) 
        ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS RowNum
    FROM sys.all_columns
)
-- 拼接所有需要的列语句
SELECT @Columns = STRING_AGG(
    CONCAT(
        'MAX(CASE WHEN RowNum = ', RowNum, ' THEN Field1 END) AS Field1_', RowNum, ',',
        'MAX(CASE WHEN RowNum = ', RowNum, ' THEN Field2 END) AS Field2_', RowNum, ',',
        'MAX(CASE WHEN RowNum = ', RowNum, ' THEN Field3 END) AS Field3_', RowNum
    ),
    ','
)
FROM RowNums;

-- 组装完整的SQL并执行
SET @SQL = CONCAT('
WITH NumberedRows AS (
    SELECT 
        ReferenceID,
        Field1,
        Field2,
        Field3,
        ROW_NUMBER() OVER (PARTITION BY ReferenceID ORDER BY (SELECT NULL)) AS RowNum
    FROM YourTableName
)
SELECT ReferenceID, ', @Columns, '
FROM NumberedRows
GROUP BY ReferenceID;
');

EXEC sp_executesql @SQL;

要是你用的是SQL Server 2022及以上版本,也可以把生成行号序列的部分换成GENERATE_SERIES(1, (SELECT MaxRowCount FROM MaxRows)),写法会更简洁。

为啥常规PIVOT不行?

普通PIVOT只能针对单个字段做行转列,而你需要同时把Field1、Field2、Field3三个字段按行号拆分,常规PIVOT没法一次性处理多字段的转列需求,所以条件聚合才是更合适的选择。

内容的提问来源于stack exchange,提问作者Anupam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:18:32