Sql Server将行展平为列

Sql Server将行展平为列,sql,sql-server,Sql,Sql Server,我有一张和这张相似的桌子 RowNumber Value colIdx 1 A 1 1 Shimano Dura-Ace 2 2 B 1 2 SRAM eTap 2 3 C

我有一张和这张相似的桌子

RowNumber   Value                     colIdx
1           A                         1
1           Shimano Dura-Ace          2     
2           B                         1
2           SRAM eTap                 2
3           C                         1
3           Campagnolo Super Record   2
我想将行展平,到目前为止,我已经得出以下结论

SELECT Rownumber,
       stuff(
               (SELECT DISTINCT ': ' + cast(value AS varchar(MAX))
                FROM groupsets t2
                WHERE t2.Rownumber = t1.Rownumber
                  FOR XML PATH('')),1,1,'')
FROM groupsets t1
GROUP BY Rownumber
ORDER BY Rownumber
但是,生成了以下内容-我希望单个字符始终作为值的前缀

RowNumber   Value
1           A: Shimano Dura-Ace
2           B: SRAM eTap
3           Campagnolo Super Record: D
我创建了一个SQL小提琴。我不知道如何通过
colIdx
订购而不需要公开它

预期产出为:

RowNumber   Value
1           A: Shimano Dura-Ace
2           B: SRAM eTap
3           D: Campagnolo Super Record

SQL Server中的数据集永远不会保证在不使用
order BY
子句的情况下以任何特定顺序返回

如果需要保证首先返回单个字符,则需要使用
ORDER BY
。例如:

SELECT Rownumber,
       STUFF(CONVERT(varchar(MAX),(SELECT DISTINCT ': ' + [value] --Is the DISTINCT required here?
                                                                  --Also, the CAST is not required, that goes on the outside of the SELECt, as you can see
                                   FROM groupsets t2
                                   WHERE t2.Rownumber = t1.Rownumber
                                   ORDER BY LEN([value]) ASC
                                   FOR XML PATH(''))),1,1,'')
FROM groupsets t1
GROUP BY Rownumber
ORDER BY Rownumber;

SQL Server中的数据集永远不会保证在不使用
order BY
子句的情况下以任何特定顺序返回

如果需要保证首先返回单个字符,则需要使用
ORDER BY
。例如:

SELECT Rownumber,
       STUFF(CONVERT(varchar(MAX),(SELECT DISTINCT ': ' + [value] --Is the DISTINCT required here?
                                                                  --Also, the CAST is not required, that goes on the outside of the SELECt, as you can see
                                   FROM groupsets t2
                                   WHERE t2.Rownumber = t1.Rownumber
                                   ORDER BY LEN([value]) ASC
                                   FOR XML PATH(''))),1,1,'')
FROM groupsets t1
GROUP BY Rownumber
ORDER BY Rownumber;

在挖掘的过程中,我看到了SQL Server 2017(和azure)中的一些新功能。下面是一个使用CTE+字符串的查询(新功能)

像这样的数据集:

CREATE TABLE groupsets
    ([Rownumber] varchar(1), [Value] varchar(max), [colidx] int)
;

INSERT INTO groupsets
    ([Rownumber], [Value], [colidx])
VALUES
    ('1', 'A',1),
    ('1', 'Shimano Dura-Ace',2),
    ('2', 'SRAM eTap',2),
    ('2', 'B',1),
    ('3', 'D',1),
    ('3', 'Campagnolo Super Record',2)
;
rownumber   Value
1   A: Shimano Dura-Ace
2   B: SRAM eTap
3   D: Campagnolo Super Record
结果:

CREATE TABLE groupsets
    ([Rownumber] varchar(1), [Value] varchar(max), [colidx] int)
;

INSERT INTO groupsets
    ([Rownumber], [Value], [colidx])
VALUES
    ('1', 'A',1),
    ('1', 'Shimano Dura-Ace',2),
    ('2', 'SRAM eTap',2),
    ('2', 'B',1),
    ('3', 'D',1),
    ('3', 'Campagnolo Super Record',2)
;
rownumber   Value
1   A: Shimano Dura-Ace
2   B: SRAM eTap
3   D: Campagnolo Super Record

(Fiddle:)

在挖掘的同时,我看到了SQL Server 2017(和azure)中的一些新功能。下面是一个使用CTE+字符串的查询(新功能)

像这样的数据集:

CREATE TABLE groupsets
    ([Rownumber] varchar(1), [Value] varchar(max), [colidx] int)
;

INSERT INTO groupsets
    ([Rownumber], [Value], [colidx])
VALUES
    ('1', 'A',1),
    ('1', 'Shimano Dura-Ace',2),
    ('2', 'SRAM eTap',2),
    ('2', 'B',1),
    ('3', 'D',1),
    ('3', 'Campagnolo Super Record',2)
;
rownumber   Value
1   A: Shimano Dura-Ace
2   B: SRAM eTap
3   D: Campagnolo Super Record
结果:

CREATE TABLE groupsets
    ([Rownumber] varchar(1), [Value] varchar(max), [colidx] int)
;

INSERT INTO groupsets
    ([Rownumber], [Value], [colidx])
VALUES
    ('1', 'A',1),
    ('1', 'Shimano Dura-Ace',2),
    ('2', 'SRAM eTap',2),
    ('2', 'B',1),
    ('3', 'D',1),
    ('3', 'Campagnolo Super Record',2)
;
rownumber   Value
1   A: Shimano Dura-Ace
2   B: SRAM eTap
3   D: Campagnolo Super Record

(Fiddle:)

也许可以在子查询中添加一个
orderby
。我可能会建议
LEN([value])
@Larnu在子查询中添加orderby会中断输出(它将作为XML输出),然后添加
CONVERT(varchar(MAX),…
。如果您不喜欢使用stuff/XML;),请查看我的答案。也许可以在子查询中添加
orderby
。我可能会建议
LEN([value])
@Larnu向子查询添加orderby会中断输出(它将作为XML输出),然后添加
CONVERT(varchar(MAX),…
。如果您不喜欢使用stuff/XML;),请查看我的答案。