SQL服务器数据透视查询 - 需要帮助

问题描述:

我需要编写SQL服务器查询以从源数据表中转储数据。SQL服务器数据透视查询 - 需要帮助

我的源表看起来是这样的 -

Cust_Id Item1_Desc_Count Item2_Desc_Count Item3_Desc_Count 
------- ---------------- ---------------- ------------ 
Cust1 10     12     9 
Cust2 7     1     3 
Cust3 12     6     0 
... 

项目主表看起来是这样的 -

Item_Id Item_Desc 
------- --------- 
1  Item1_Desc 
2  Item2_Desc 
3  Item3_Desc 

请注意,项目说明在列名称中使用源表格。

但我需要输出为 -

Cust_Id Item_Id Count 
-------- --------- ------ 
Cust1  1   10 
Cust1  2   12 
Cust1  3   9 
Cust2  1   7 
Cust2  2   1 
Cust2  3   3 
Cust3  1   12 
... 

谁能帮助我实现这个使用SQL查询?

这是一个更动态的方法。无需指定所有项目计数列。

The CROSS APPLY will UNPIVOT Source Table。

我应该添加UNPIVOT会更高效,但我假设您有很多计数列。


创建示例数据

Declare @Source table (Cust_Id varchar(25),Item1_Desc_Count int,Item2_Desc_Count int,Item3_Desc_Count int) 
Insert Into @Source values 
('Cust1',10,12,9), 
('Cust2', 7, 1,3), 
('Cust3',12, 6,0) 

Declare @Item table (Item_Id int,Item_Desc varchar(50)) 
Insert Into @Item values 
(1,'Item1_Desc'), 
(2,'Item2_Desc'), 
(3,'Item3_Desc') 

代码示例

Select B.Cust_ID 
     ,C.Item_ID 
     ,Count = B.Value 
From (Select XMLData = cast((Select * From @Source for XML Raw) as XML)) A 
Cross Apply (
       Select Cust_ID = r.value('@Cust_Id','varchar(50)') 
         ,Item = attr.value('local-name(.)','varchar(100)') 
         ,Value = attr.value('.','varchar(max)') 
       From A.XMLData.nodes('/row') as A(r) 
       Cross Apply A.r.nodes('./@*') AS B(attr) 
       Where attr.value('local-name(.)','varchar(100)') not in ('Cust_ID','OtherFieldsToExclude') 
      ) B 
Join @Item C on B.Item Like C.Item_Desc+'%' 

返回

Cust_ID Item_ID Count 
Cust1 1  10 
Cust1 2  12 
Cust1 3  9 
Cust2 1  7 
Cust2 2  1 
Cust2 3  3 
Cust3 1  12 
Cust3 2  6 
Cust3 3  0 

编辑 - UNPIVOT选项

Select A.Cust_ID 
     ,B.Item_ID 
     ,Count = A.Value 
From (
     Select Cust_Id,Item,value 
     From @Source 
     Unpivot (Value for Item in (Item1_Desc_Count,Item2_Desc_Count,Item3_Desc_Count)) u 
     ) A 
Join @Item B on A.Item Like B.Item_Desc+'%' 

如果我理解,你愿意加入你和你的主表的内容源表的列名。

一个支点不能这样工作。枢轴是当你想将你的数据,如

Cust1 10 7 12 Cust2 12 1 6 Cust3 9 3 0

(检查本例:https://blogs.msdn.microsoft.com/spike/2009/03/03/pivot-tables-in-sql-server-a-simple-sample/

在这种情况下,我把这个解决方案(但的Item_ID将被硬编码):

select Cust_Id, 1, Item1_Desc_Count as count FROM SourceTable UNION ALL select Cust_Id, 2, Item2_Desc_Count as count FROM SourceTable UNON ALL ...etc

我同意,这是不是很优雅,但如果没有源表中的列名,并在t时的item_descs之间的完美匹配它的简单和灵活他掌握表