[英]SQL Converting Columns to Rows
I want to perform the following conversion:我想执行以下转换:
Seniority Price Rating
---------------------------
1 P1 R1
2 P2 R2
3 P3 R3
to至
Value RowId ColId
------------------
1 0 0
P1 0 1
R1 0 2
2 1 0
P2 1 1
R2 1 2
3 2 0
P3 2 1
R3 2 2
If possible I would like to preserve the field name as well in the transformed table, ie all rows with rowid=0 will have Seniority added as a field, rowid=1 will have Price, so on.如果可能的话,我想在转换后的表中保留字段名称,即所有 rowid=0 的行都将添加优先级作为字段,rowid=1 将具有价格,依此类推。
Here is an option using JSON if 2016+ An XML version is available for older version.这是一个使用 JSON 的选项,如果 2016+ XML 版本可用于旧版本。
Example例子
Declare @YourTable Table ([Seniority] varchar(50),[Price] varchar(50),[Rating] varchar(50))
Insert Into @YourTable Values
(1,'P1','R1')
,(2,'P2','R2')
,(3,'P3','R3')
Select B.Value
,A.RowID
,B.ColID
From (Select *
,RowID = row_number() over (order by (select null)) - 1
From @YourTable --<<< Replace with virtually any table.
) A
Cross Apply (
Select *
,ColID = row_number() over (order by (select null)) - 1
From OpenJson( (Select A.* For JSON Path,Without_Array_Wrapper,INCLUDE_NULL_VALUES ) )
Where [Key] not in ('RowID')
) B
Returns退货
EDIT - Just for Fun, the XML version编辑 - 只是为了好玩,XML 版本
Select C.Value
,A.RowID
,C.ColID
From (Select *
,RowID = row_number() over (order by (select null)) - 1
From @YourTable
) A
Cross Apply ( values ( convert(xml,(Select A.* for XML RAW)) ) ) B(XMLData)
Cross Apply (
Select ColID = row_number() over( order by (select null)) - 1
,Value = xAttr.value('.','varchar(max)')
From XMLData.nodes('//@*') xNode(xAttr)
Where xAttr.value('local-name(.)', 'varchar(100)') not in ('RowID')
) C
EDIT -- XML Version to ALLOW NULL values编辑——XML 版本允许 NULL 值
Declare @YourTable Table ([Seniority] varchar(50),[Price] varchar(50),[Rating] varchar(50))
Insert Into @YourTable Values
(1,'P1','R1')
,(2,'P2','R2')
,(3,NULL,'R3') -- Forced a NULL value
Select C.Value
,A.RowID
,C.ColID
From (Select *
,RowID = row_number() over (order by (select null)) - 1
From @YourTable
) A
Cross Apply ( values ( convert(xml,(Select A.* for XML RAW,ELEMENTS XSINIL)) ) ) B(XMLData)
Cross Apply (
Select Item = attr.value('local-name(.)','varchar(100)')
,Value = attr.value('.','varchar(max)')
,ColID = row_number() over (order by (select null)) - 1
From XMLData.nodes('/row') as C1(nd)
Cross Apply C1.nd.nodes('./*') as C2(attr)
Where attr.value('local-name(.)','varchar(100)') not in ('RowID')
) C
Returns退货
Value RowID ColID
1 0 0
P1 0 1
R1 0 2
0 0 3
2 1 0
P2 1 1
R2 1 2
1 1 3
3 2 0
2 1 --<< Notice NULLs return as Empty Strings
R3 2 2
2 2 3
As a general approach, union all
works:作为一般方法, union all
工作:
select seniority, 'seniority' as which, seniority - 1, 0
from t
union all
select p1, 'p1' as which, seniority - 1, 1
from t
union all
select r1, 'r1' as which, seniority - 1, 2
from t;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.