将行转换为列

Transform rows into columns

我有一个 table 每个项目编号有几行,即

Itemno  Component  Fabric     Fabric %
------  ---------  ------     --------
1       Back       Cotton     100
1       Face       Viscose    67
1       Face       Nylon      27
1       Face       Elastane   6
2       Main       Cotton     100
3       Back       Nylon      50
3       Back       Viscose    50
3       Face       Cotton     100 

我想将其转换为每个项目编号一行,将组件、面料和面料 % 列连接成一个新列。这将很容易使用 PIVOT,但是增加的复杂性是如果两个相同,我不想重复组件列。

编辑 - 忘了说,当有多种面料时,我希望它们从最大到最小降序排列。

使用上面的例子,我想要的输出是:

Itemno  Composition
------  -----------
1       Back 100% Cotton, Face 67% Viscose, 27% Nylon, 6% Elastane
2       Main 100% Cotton
3       Back 50% Nylon, 50% Viscose, Face 100% Cotton

提前致谢!

编辑 - 我正在使用 Microsoft SQL Server 2012!

使用 STUFF 生成分隔列表,您只需首先创建一个不同组件的中间列表。

像这样的东西应该适合你。

DECLARE @Something TABLE
(
    ItemNo INT
    , Component VARCHAR(10)
    , Fabric VARCHAR(20)
    , FabricPercent INT
)

INSERT @Something
(
    ItemNo,
    Component,
    Fabric,
    FabricPercent
)
VALUES
(1, 'Back', 'Cotton', 100),
(1, 'Face', 'Viscose', 67),
(1, 'Face', 'Nylon', 27),
(1, 'Face', 'Elastane', 6),
(2, 'Main', 'Cotton', 100),
(3, 'Back', 'Nylon', 50),
(3, 'Back', 'Viscose', 50),
(3, 'Face', 'Cotton', 100 )
;

WITH GroupedComponents AS
(
    SELECT s.ItemNo
        , s.Component + STUFF((SELECT ', ' + CONVERT(VARCHAR(4), s2.FabricPercent) + '% ' + s2.Fabric
                FROM @Something s2
                WHERE s2.ItemNo = s.ItemNo
                    AND s2.Component = s.Component
                ORDER BY s2.FabricPercent DESC
                FOR XML PATH('')), 1, 1, '') AS Composition
    FROM @Something s
    GROUP BY s.ItemNo, s.Component
)

SELECT gc.ItemNo
    , STUFF((SELECT ', ' + gc2.Composition
            FROM GroupedComponents gc2
            WHERE gc2.ItemNo = gc.ItemNo
            FOR XML PATH('')), 1, 1,'') AS FullComposition
FROM GroupedComponents gc
GROUP BY gc.ItemNo