[英]Write a SQL query to convert table from A to B
我有一個數據庫表(表 A),在 SQL Server 2016 中如下所示:
表 A:
ID Group 2018 2019 2020
-----------------------------------------
ID1 Group A 200 300 400
ID2 Group B 100 800 ---
ID2 Group B ---- 500 300
我想編寫一個 SQL 查詢或類似的東西或報告工具來生成報告/表格(將表格 A 轉換為表格 B),如下所示:
表 B:
ID Group - Year - Value
----------------------------------------
ID1 Group A 2018 200
ID1 Group A 2019 300
ID1 Group A 2020 400
ID2 Group B 2018 100
ID2 Group B 2019 800
ID2 Group B 2019 500
ID2 Group B 2020 300
如果可以通過編寫 SQL 查詢來實現,那就太好了。 如果它需要使用編程語言編寫程序或使用工具,那也可以,但請告訴我使用什么以及如何實現(我知道一些 C# 編程)。
(我知道我不應該使用 ID 和 Group 作為列名。我不會在數據庫表中真正使用該名稱,只是為了簡化這里的問題)
任何人都可以幫忙嗎? 非常感謝!
規范方法使用union all
:
select id, group, 2018 as year, "2018" from t
union all
select id, group, 2019 as year, "2019" from t
union all
select id, group, 2020 as year, "2018" from t;
但是,在 SQL 服務器中,我強烈建議apply
:
select t.id, t.group, v.*
from t cross apply
(values (2018, [2018]), (2019, [2019]), (2020, [2020])
) v(year, value)
where v.value is not null;
以防萬一您隨着時間的推移有可變列或附加列。
請注意,您只需要 EXCLUDE 某些列並省略 NULLS。
全面披露:Gordon 的 APPLY 性能更佳。
例子
Select A.[ID]
,A.[Group]
,[Year] = B.[Key]
,[Value] = try_convert(int,B.[Value]) --<< choose the proper data type (optional)
From YourTable A
Cross Apply (
Select *
From OpenJson( (Select A.* For JSON Path,Without_Array_Wrapper ) )
Where [Key] not in ('ID','Group')
) B
退貨
ID Group Year Value
ID1 Group A 2018 200
ID1 Group A 2019 300
ID1 Group A 2020 400
ID2 Group B 2018 100
ID2 Group B 2019 800
ID2 Group B 2019 500
ID2 Group B 2020 300
編輯——XML 版本如果不是 2016+
Select A.[ID]
,A.[Group]
,[Year] = replace(replace(C.[Item],'X003',''),'_','')
,[Value] = try_convert(int,C.[Value]) --<< choose the proper data type (optional)
From YourTable A
Cross Apply ( values ( convert(xml,(Select A.* for XML RAW)) ) ) B(XMLData)
Cross Apply (
Select Item = xAttr.value('local-name(.)', 'varchar(100)')
,Value = xAttr.value('.','varchar(max)')
From XMLData.nodes('//@*') xNode(xAttr)
Where xAttr.value('local-name(.)', 'varchar(100)') not in ('ID','Group')
) C
使用 UNPIVOT 的解決方案:
select * from A
UNPIVOT
(
[value] for [Year] in ([2018],[2019],[2020])
)u;
希望能幫助到你。!
這是我的解決方案,完全符合您的需求
我用方括號將關鍵字和年份作為列名括起來
Select id, [Group], [year], value
from
(
select id, [Group], 2018 as [year], [2018] as value from a
union all
select id, [Group], 2019 as [year], [2019] as value from a
union all
select id, [Group], 2020 as [year], [2020] as value from a
) Q
Where value is not null
order by id, [Group], [year]
這是小提琴
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.