我想使用pivot SQL查询来构造一个结果表,其中连接文本作为数据透视表的DATA部分中的结果。
即。我使用简单的选择得到以下结果:
+------------+-----------------+---------------+ | Event Name | Resource Type | Resource Name | +------------+-----------------+---------------+ | Event 1 | Resource Type 1 | Resource 1 | | Event 1 | Resource Type 1 | Resource 2 | | Event 1 | Resource Type 2 | Resource 3 | | Event 1 | Resource Type 2 | Resource 4 | | Event 1 | Resource Type 3 | Resource 5 | | Event 1 | Resource Type 3 | Resource 6 | | Event 1 | Resource Type 3 | Resource 7 | | Event 1 | Resource Type 4 | Resource 8 | | Event 2 | Resource Type 5 | Resource 1 | | Event 2 | Resource Type 2 | Resource 3 | | Event 2 | Resource Type 3 | Resource 11 | | Event 2 | Resource Type 3 | Resource 12 | | Event 2 | Resource Type 3 | Resource 13 | | Event 2 | Resource Type 4 | Resource 14 | | Event 2 | Resource Type 5 | Resource 9 | | Event 2 | Resource Type 5 | Resource 16 | +------------+-----------------+---------------+
我想构建一个如下所示的结果查询:
+---------------------+------------------------+------------------------+---------------------------------------+-----------------+-------------------------------------+ | Event/Resource Type | Resource Type 1 | Resource Type 2 | Resource Type 3 | Resource Type 4 | Resource Type 5 | +---------------------+------------------------+------------------------+---------------------------------------+-----------------+-------------------------------------+ | Event 1 | Resource 1, Resource 2 | Resource 3, Resource 4 | Resource 5, Resource 6, Resource 7 | Resource 8 | NULL | | Event 2 | NULL | Resource 3 | Resource 11, Resource 12, Resource 13 | Resource 14 | Resource 1, Resource 9, Resource 16 | +---------------------+------------------------+------------------------+---------------------------------------+-----------------+-------------------------------------+
我知道如何在ms-sql中使用PIVOT语句,但我不知道如何将资源名称聚合为每种资源类型的逗号分隔项的串联。
P.S 我还可以使用SSRS 2008-R2提供的Martix解决方案,使用Report Builde 3,第一个表作为我的数据集,并创建一个矩阵,将资源名称聚合成逗号分隔的字符串。
答案 0 :(得分:16)
为了获得结果,首先应将值连接到逗号分隔列表中。
我会使用CROSS APPLY
和FOR XML PATH
:
SELECT distinct e.[Event Name],
e.[Resource Type],
LEFT(r.ResourceName , LEN(r.ResourceName)-1) ResourceName
FROM yourtable e
CROSS APPLY
(
SELECT r.[Resource Name] + ', '
FROM yourtable r
where e.[Event Name] = r.[Event Name]
and e.[Resource Type] = r.[Resource Type]
FOR XML PATH('')
) r (ResourceName)
见SQL Fiddle with Demo。给你结果:
| EVENT NAME | RESOURCE TYPE | RESOURCENAME |
------------------------------------------------------------------------
| Event 1 | Resource Type 1 | Resource 1, Resource 2 |
| Event 1 | Resource Type 2 | Resource 3, Resource 4 |
| Event 1 | Resource Type 3 | Resource 5, Resource 6, Resource 7 |
| Event 1 | Resource Type 4 | Resource 8 |
| Event 2 | Resource Type 2 | Resource 3 |
| Event 2 | Resource Type 3 | Resource 11, Resource 12, Resource 13 |
| Event 2 | Resource Type 4 | Resource 14 |
| Event 2 | Resource Type 5 | Resource 1, Resource 9, Resource 16 |
然后,您将PIVOT
应用于此结果:
SELECT [Event Name],
[Resource Type 1], [Resource Type 2],
[Resource Type 3], [Resource Type 4],
[Resource Type 5]
FROM
(
SELECT distinct e.[Event Name],
e.[Resource Type],
LEFT(r.ResourceName , LEN(r.ResourceName)-1) ResourceName
FROM yourtable e
CROSS APPLY
(
SELECT r.[Resource Name] + ', '
FROM yourtable r
where e.[Event Name] = r.[Event Name]
and e.[Resource Type] = r.[Resource Type]
FOR XML PATH('')
) r (ResourceName)
) src
pivot
(
max(ResourceName)
for [Resource Type] in ([Resource Type 1], [Resource Type 2],
[Resource Type 3], [Resource Type 4],
[Resource Type 5])
) piv
见SQL Fiddle with Demo。您的最终结果将是:
| EVENT NAME | RESOURCE TYPE 1 | RESOURCE TYPE 2 | RESOURCE TYPE 3 | RESOURCE TYPE 4 | RESOURCE TYPE 5 |
----------------------------------------------------------------------------------------------------------------------------------------------------------------
| Event 1 | Resource 1, Resource 2 | Resource 3, Resource 4 | Resource 5, Resource 6, Resource 7 | Resource 8 | (null) |
| Event 2 | (null) | Resource 3 | Resource 11, Resource 12, Resource 13 | Resource 14 | Resource 1, Resource 9, Resource 16 |
答案 1 :(得分:4)
这在SQL 2008中适用于我,它是动态的 - 将处理额外的Resource Type
IF OBJECT_ID('tempdb..#test') IS NOT NULL
DROP TABLE #test
GO
CREATE TABLE #test
(
eventName VARCHAR(30),
resourceType VARCHAR(30),
resourceName VARCHAR(30)
);
INSERT INTO #test
VALUES ('Event 1','Resource Type 1','Resource 1'),
('Event 1','Resource Type 1','Resource 2'),
('Event 1','Resource Type 2','Resource 3'),
('Event 1','Resource Type 2','Resource 4'),
('Event 1','Resource Type 3','Resource 5'),
('Event 1','Resource Type 3','Resource 6'),
('Event 1','Resource Type 3','Resource 7'),
('Event 1','Resource Type 4','Resource 8'),
('Event 2','Resource Type 5','Resource 1'),
('Event 2','Resource Type 2','Resource 3'),
('Event 2','Resource Type 3','Resource 11'),
('Event 2','Resource Type 3','Resource 12'),
('Event 2','Resource Type 3','Resource 13'),
('Event 2','Resource Type 4','Resource 14'),
('Event 2','Resource Type 5','Resource 9'),
('Event 2','Resource Type 5','Resource 16');
DECLARE @resourceTypes VARCHAR(max);
SELECT @resourceTypes = stuff((SELECT DISTINCT ',[' + resourceType + ']'
FROM #test
FOR xml path('')), 1, 1, '');
DECLARE @query NVARCHAR(max);
SET @query = 'SELECT *
FROM (SELECT eventName,
resourceType,
stuff((SELECT '','' + resourceName + ''''
FROM #test b
WHERE a.eventName = b.eventName
AND a.resourceType = b.resourceType
FOR xml path('''')), 1, 1, '''') resourceName
FROM #test a
GROUP BY eventName,
resourceType) AS data PIVOT (max(resourceName) FOR resourceType IN (' + @resourceTypes + ')) AS pvt';
EXEC(@query);
DROP TABLE #test;
答案 2 :(得分:2)
在报告构建器中,您应使用表或矩阵向导,然后执行以下操作:
Resource Type
字段作为列组。Event Name
字段作为行组。Resource Name
字段作为详细信息,将必须使用聚合函数,例如Count
。在此阶段完成向导,然后完成编辑Resource Name
单元格作为表达式。将表达式替换为:
=Join( LookupSet( Fields!EVENT_NAME.Value + Fields!RESOURCE_TYPE.Value,
Fields!EVENT_NAME.Value + Fields!RESOURCE_TYPE.Value,
Fields!RESOURCE_NAME.Value, "DataSet1"), ", ")
现在已经过试用和测试:
答案 3 :(得分:0)
完整的工作示例:
SET NOCOUNT ON
GO
DECLARE @SourceTable TABLE
(
EventName NVARCHAR(10)
,ResourceType NVARCHAR(20)
,ResourceName NVARCHAR(20)
)
INSERT INTO @SourceTable(EventName,ResourceType,ResourceName)
VALUES ('Event 1','Resource Type 1','Resource 1')
,('Event 1','Resource Type 1','Resource 2')
,('Event 1','Resource Type 2','Resource 3')
,('Event 1','Resource Type 2','Resource 4')
,('Event 1','Resource Type 3','Resource 5')
,('Event 1','Resource Type 3','Resource 6')
,('Event 1','Resource Type 3','Resource 7')
,('Event 1','Resource Type 4','Resource 8')
,('Event 2','Resource Type 5','Resource 1')
,('Event 2','Resource Type 2','Resource 3')
,('Event 2','Resource Type 3','Resource 11')
,('Event 2','Resource Type 3','Resource 12')
,('Event 2','Resource Type 3','Resource 13')
,('Event 2','Resource Type 4','Resource 14')
,('Event 2','Resource Type 5','Resource 9')
,('Event 2','Resource Type 5','Resource 16')
;WITH SourceTable AS
(
SELECT DISTINCT ST1.EventName
,ST1.ResourceType
,(SELECT SUBSTRING((SELECT ',' +ResourceName
FROM @SourceTable AS ST2
WHERE ST1.EventName=ST2.EventName AND ST1.ResourceType=ST2.ResourceType
FOR XML PATH('')),2,200) AS CSV) AS ResourceName
FROM @SourceTable AS ST1
)
SELECT EventName
,[Resource Type 1]
,[Resource Type 2]
,[Resource Type 3]
,[Resource Type 4]
,[Resource Type 5]
FROM
(
SELECT EventName
,ResourceType
,ResourceName
FROM SourceTable
) PivotSource
PIVOT
(
MAX(ResourceName) FOR ResourceType IN ([Resource Type 1],[Resource Type 2],[Resource Type 3],[Resource Type 4],[Resource Type 5])
) PivotTable
SET NOCOUNT OFF
GO