我有一个简单的数据集,如下所示:
Name Code
A A-One
A A-Two
B B-One
C C-One
C C-Two
C C-Three
我想输出它,就像这样:
Name Code1 Code2 Code3 Code4 Code...n ...
A A-One A-Two
B B-One
C C-One C-Two C-Three
对于每个“名称”值,可以存在数量不确定的“代码”值。
我一直在研究Pivot SQL的各种示例(包括简单的Pivot sql和使用XML函数的sql吗?),但我一直无法弄清楚-甚至无法理解它是否可能。
我将不胜感激。
谢谢!
答案 0 :(得分:1)
像这样尝试:
DECLARE @tbl TABLE([Name] VARCHAR(100),Code VARCHAR(100));
INSERT INTO @tbl VALUES
('A','A-One')
,('A','A-Two')
,('B','B-One')
,('C','C-One')
,('C','C-Two')
,('C','C-Three');
SELECT p.*
FROM
(
SELECT *
,CONCAT('Code',ROW_NUMBER() OVER(PARTITION BY [Name] ORDER BY Code)) AS ColumnName
FROM @tbl
)t
PIVOT
(
MAX(Code) FOR ColumnName IN (Code1,Code2,Code3,Code4,Code5 /*add as many as you need*/)
)p;
此行
,CONCAT('Code',ROW_NUMBER() OVER(PARTITION BY [Name] ORDER BY Code)) AS ColumnName
将使用分区的ROW_NUMBER
,以便为每个代码创建编号为的列名。其余的很简单PIVOT
...
CREATE TABLE TblTest([Name] VARCHAR(100),Code VARCHAR(100));
INSERT INTO TblTest VALUES
('A','A-One')
,('A','A-Two')
,('B','B-One')
,('C','C-One')
,('C','C-Two')
,('C','C-Three');
DECLARE @cols VARCHAR(MAX);
WITH GetMaxCount(mc) AS(SELECT TOP 1 COUNT([Code]) FROM TblTest GROUP BY [Name] ORDER BY COUNT([Code]) DESC)
SELECT @cols=STUFF(
(
SELECT CONCAT(',Code',Nmbr)
FROM
(SELECT TOP((SELECT mc FROM GetMaxCount)) ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) FROM master..spt_values) t(Nmbr)
FOR XML PATH('')
),1,1,'');
DECLARE @sql VARCHAR(MAX)=
'SELECT p.*
FROM
(
SELECT *
,CONCAT(''Code'',ROW_NUMBER() OVER(PARTITION BY [Name] ORDER BY Code)) AS ColumnName
FROM TblTest
)t
PIVOT
(
MAX(Code) FOR ColumnName IN (' + @cols + ')
)p;';
EXEC(@sql);
GO
DROP TABLE TblTest;
如您所见,为了反映实际的列数,唯一更改的部分是PIVOT
的{{1}}子句中的列表。
您可以创建一个类似于IN()
的字符串并动态生成该语句。可以通过Code1,Code2,Code3,...CodeN
触发。
我更喜欢第一种方法。动态创建的SQL非常强大,但也可能会让人头痛...