将行转换为列

时间:2017-06-20 15:55:48

标签: sql sql-server pivot concatenation

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

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!

1 个答案:

答案 0 :(得分:1)

使用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