Sql Server将行展平为列

时间:2018-03-02 11:34:11

标签: sql sql-server

我有一张与此相似的表

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小提琴here。我不确定如何通过colIdx订购而不需要公开它?

预期输出为:

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

2 个答案:

答案 0 :(得分:1)

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;

答案 1 :(得分:1)

虽然挖掘了一点,但我在SQL Server 2017(和azure)中看到了一些新功能。这是一个使用CTE + STRING_AGG (新功能)的查询。

WITH groupsetsOrdered AS
(
    SELECT top 100000 rownumber, [value], [colIdx]
    FROM groupsets
    ORDER BY rownumber, colidx 
)
select rownumber as [RowNumber], string_agg([value], ': ') as [Value]
from groupsetsOrdered
group by rownumber
order by rownumber

数据集如:

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

(小提琴:http://sqlfiddle.com/#!18/707ec/9/0