sql 服务器数据透视查询 - 需要帮助
sql server pivot query - help required
我需要编写 SQL 服务器查询以从源 table 中转换数据。
我的来源 table 看起来像这样 -
Cust_Id Item1_Desc_Count Item2_Desc_Count Item3_Desc_Count
------- ---------------- ---------------- ------------
Cust1 10 12 9
Cust2 7 1 3
Cust3 12 6 0
...
物品大师table看起来像这样-
Item_Id Item_Desc
------- ---------
1 Item1_Desc
2 Item2_Desc
3 Item3_Desc
请注意,项目描述用于来源 table 中的列名称。
我需要我的输出是 -
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 查询帮助我实现此目的吗?
这是一种更动态的方法。无需指定所有项目计数列。
交叉应用 将 UNPIVOT 源 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+'%'
Returns
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+'%'
如果我明白了,你想加入你的源 table 列名和你的主人 table 的内容。
枢轴不是这样工作的。一个枢轴是当你想像
那样转动你的数据时
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
我同意它不是很优雅,但如果源 table 列名称与主 table 中的 item_descs 之间没有完美匹配,它会简单灵活
我需要编写 SQL 服务器查询以从源 table 中转换数据。
我的来源 table 看起来像这样 -
Cust_Id Item1_Desc_Count Item2_Desc_Count Item3_Desc_Count
------- ---------------- ---------------- ------------
Cust1 10 12 9
Cust2 7 1 3
Cust3 12 6 0
...
物品大师table看起来像这样-
Item_Id Item_Desc
------- ---------
1 Item1_Desc
2 Item2_Desc
3 Item3_Desc
请注意,项目描述用于来源 table 中的列名称。
我需要我的输出是 -
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 查询帮助我实现此目的吗?
这是一种更动态的方法。无需指定所有项目计数列。
交叉应用 将 UNPIVOT 源 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+'%'
Returns
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+'%'
如果我明白了,你想加入你的源 table 列名和你的主人 table 的内容。
枢轴不是这样工作的。一个枢轴是当你想像
那样转动你的数据时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
我同意它不是很优雅,但如果源 table 列名称与主 table 中的 item_descs 之间没有完美匹配,它会简单灵活