我正在尝试制作以下结构
ROW | GROUP | ORDER | COL_NAME | VALUE
---------------------------------------------
1 | 10 | 10 | FIRST_COL | Value1
2 | 10 | 10 | FIRST_COL | Value2
3 | 10 | 10 | FIRST_COL | Value3
4 | 10 | 20 | SECOND_COL| Val1
5 | 10 | 20 | SECOND_COL| Val2
6 | 20 | 10 | THIRD_COL | Opt3
...
到
FIRST_COL | SECOND_COL | THIRD_COL
-----------------------------------------------------
Value1 | Val1 | Opt3
Value2 | Val2 |
Value3 | |
我现在有什么:
declare @cols varchar(max),
@query varchar(max)
select @cols = stuff((select ',' + quotename([COL_NAME])
from mt
group by [COL_NAME]
for xml path(''), type).value('.', 'varchar(max)'), 1, 1, '');
set @query = 'select ' + @cols + ' from (
select [COL_NAME], [VALUE]
from mt
) x
pivot (
min([VALUE])
for [COL_NAME] in (' + @cols + ')
) p
';
execute(@query);
当前代码仅显示最小值(因为它设置为min([VALUES])
),因此只显示Value1,Val1和Opt3,但我的问题是,如何修改代码以便我得到适当的表/视图?
谢谢!
答案 0 :(得分:2)
这样的东西?
Declare @YourTable table ([ROW] int,[GROUP] int,[ORDER] int,[COL_NAME] varchar(50),[VALUE] varchar(50))
Insert Into @YourTable Values
(1,10,10,'FIRST_COL' ,'Value1'),
(2,10,10,'FIRST_COL' ,'Value2'),
(3,10,10,'FIRST_COL' ,'Value3'),
(4,10,20,'SECOND_COL','Val1'),
(5,10,20,'SECOND_COL','Val2'),
(6,20,10,'THIRD_COL' ,'Opt3')
;with cteBase as (
Select *
,RowNr = Row_Number() over (Partition By [COL_NAME] Order by [ROW])
From @YourTable
)
Select First_Col = max(case when [COL_NAME]='FIRST_COL' then Value else '' end)
,Second_Col = max(case when [COL_NAME]='SECOND_COL' then Value else '' end)
,Third_Col = max(case when [COL_NAME]='THIRD_COL' then Value else '' end)
From cteBase
Group By RowNr
返回
First_Col Second_Col Third_Col
Value1 Val1 Opt3
Value2 Val2
Value3
答案 1 :(得分:2)
试试这样:
DECLARE @tbl TABLE([ROW] INT,[GROUP] INT,[ORDER] INT,[COL_NAME] VARCHAR(100),VALUE VARCHAR(100));
INSERT INTO @tbl VALUES
(1,10,10,'FIRST_COL','Value1')
,(2,10,10,'FIRST_COL','Value2')
,(3,10,10,'FIRST_COL','Value3')
,(4,10,20,'SECOND_COL','Val1')
,(5,10,20,'SECOND_COL','Val2')
,(6,20,10,'THIRD_COL','Opt3');
WITH Sorted AS
(
SELECT tbl.*
,ROW_NUMBER() OVER(PARTITION BY tbl.[COL_NAME] ORDER BY tbl.[ROW]) AS SortInx
FROM @tbl AS tbl
)
SELECT MAX(CASE WHEN Sorted.[COL_NAME]='FIRST_COL' THEN Sorted.[VALUE] END) AS FIRST_COL
,MAX(CASE WHEN Sorted.[COL_NAME]='SECOND_COL' THEN Sorted.[VALUE] END) AS SECOND_COL
,MAX(CASE WHEN Sorted.[COL_NAME]='THIRD_COL' THEN Sorted.[VALUE] END) AS THIRD_COL
FROM Sorted
GROUP BY SortInx
答案 2 :(得分:2)
我相信你需要这个:
set @query = 'select ' + @cols + ' from (
select [COL_NAME], [VALUE], ROW_NUMBER() OVER (PARTITION BY [COL_NAME] ORDER BY (SELECT NULL)) as seqnum
from mt
) x
pivot (
min([VALUE])
for [COL_NAME] in (' + @cols + ')
) p
';
pivot
使用子查询中的所有列。您只需要用一个来区分具有相同列名的行。
答案 3 :(得分:0)
正如他所说,您需要使用RowNumber()填充COL_NAME上的Row列,这样您的数据就会如下所示。
ROW | GROUP | ORDER | COL_NAME | VALUE
---------------------------------------------
1 | 10 | 10 | FIRST_COL | Value1
2 | 10 | 10 | FIRST_COL | Value2
3 | 10 | 10 | FIRST_COL | Value3
1 | 10 | 20 | SECOND_COL| Val1
2 | 10 | 20 | SECOND_COL| Val2
1 | 20 | 10 | THIRD_COL | Opt3
...
然后,只需在SQL
中包含该列set @query = 'select [Row], ' + @cols + ' from (
select [Row],[COL_NAME], [VALUE]
from mt
) x
pivot (
min([VALUE])
for [COL_NAME] in (' + @cols + ')
) p
';
execute(@query);
然后,你有
ROW FIRST_COL SECOND_COL THIRD_COL
1 Value1 Val1 Opt3
2 Value2 Val2 NULL
3 Value3 NULL NULL