繁体   English   中英

如何在SQL-SERVER中使用PIVOT将多行数据转换为多列?

[英]How to convert multiple row data to multiple column using PIVOT in SQL-SERVER?

我正在寻找一种使用Pivot在SQL Server中将行转换为列的有效方法。 我已经使用带有案例和集合的聚合函数获得了输出,但是我希望PIVOT是处理这种行到列转换的明确方法。

示例数据是

-------------------------------------
| ID | Row | First |Last | Postal |
------------------------------------
| 1  | 1   | John  | Doe | B4K    |
| 1  | 2   | Matt  | Kev | 2H1    |
| 2  | 1   | Hary  | Lot | L26    |
| 2  | 2   | Fork  | Har | M3R    |
| 3  | 1   | Yuv   | Hal | L39    |
------------------------------------

这是我的结果:

| ID | First1 |Last1 | Postal1 | First2 |Last2 | Postal2 |
 -----------------------------------------------------------
| 1  | John   | Doe  | B4K     | Matt   | Kev  | 2H1     |
| 2  | Hary   | Lot  | L26     | Fork   | Har  | M3R     |
| 3  | Yuv    | Hal  | L39     | NULL   | NULL | NULL    |
-----------------------------------------------------------

如何使用PIVOT获得此结果?

您的数据:

CREATE TABLE #Test (
    ID          INT,
    [Row]       INT,
    [First]     VARCHAR(32),
    [Last]      VARCHAR(32),
    [Postal]    VARCHAR(32)
)

INSERT #Test
VALUES
(1, 1, 'John', 'Doe', 'B4K'),
(1, 2, 'Matt', 'Kev', '2H1'),
(2, 1, 'Hary', 'Lot', 'L26'),
(2, 2, 'Fork', 'Har', 'M3R'),
(3, 1, 'Yuv', 'Hal', 'L39')

为了获得预期的结果,您必须在使用PIVOT之前先使用UNPIVOT ,如下所示:

SELECT *
FROM (
    SELECT ID, ITEM + CAST([Row] AS VARCHAR) AS Name, VALUE
    FROM (
        SELECT *
        FROM #Test
    )s
    UNPIVOT
    (VALUE FOR Item IN ([First], [Last], [Postal])) p
) src
PIVOT
(MAX(VALUE) FOR Name IN ([First1], [Last1], [Postal1], [First2], [Last2], [Postal2])
) pvt

显然,该行(MAX(VALUE) FOR Name IN ([First1], [Last1], [Postal1], [First2], [Last2], [Postal2])取决于字段[Row]中不同值的计数,因此查询必须动态创建。

您可以动态创建一个将使用OUTER APPLY的查询,而不是使用UNPIVOT/PIVOT

SELECT DISTINCT ID,
    t1.[First]  AS First1,
    t1.[Last]   AS Last1,
    t1.Postal   AS Postal1,
    t2.[First]  AS First2,
    t2.[Last]   AS Last2,
    t2.Postal   AS Postal2
FROM #Test t

    OUTER APPLY (
        SELECT TOP 1 [First], [Last], [Postal]
        FROM #Test
        WHERE ID = t.ID
            AND [Row] = 1
        ) t1

    OUTER APPLY (
        SELECT TOP 1 [First], [Last], [Postal]
        FROM #Test
        WHERE ID = t.ID
            AND [Row] = 2
        ) t2

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM