2012-04-25 30 views
0

我有一个带有XML类型列的表。该列包含可能在记录之间不同的属性的动态列表。通过动态列表的T-SQL GROUP BY

我想通过这些属性GROUP BY COUNT,而不必单独通过每个属性的表。

例如,一条记录可能具有属性A,B和C,另一条记录可能有B,C,D,当我执行GROUP BY COUNT时,我会得到A = 1,B = 2,C = 2和D = 1。

有没有简单的方法来做到这一点?

编辑在回答安德鲁answer

因为我的这个结构的认识是肤浅的,充其量我与它摆弄得到它做我想做的。在我的实际代码中,我需要按TimeRange进行分组,并且只根据名称选择一些属性。我粘贴下面的实际查询:

WITH attributes AS (
    SELECT 
    Timestamp, 
    N.a.value('@name[1]', 'nvarchar(max)') AS AttributeName, 
    N.a.value('(.)[1]', 'nvarchar(max)') AS AttributeValue 
    FROM MyTable 
    CROSS APPLY AttributesXml.nodes('/Attributes/Attribute') AS N(a) 
) 
SELECT Datepart(dy, Timestamp), AttributeValue, COUNT(AttributeValue) 
FROM attributes 
WHERE AttributeName IN ('AttributeA', 'AttributeB') 
GROUP BY Datepart(dy, Timestamp), AttributeValue 

作为一个侧面说明:有没有什么办法可以进一步减少呢?

+0

这是一个旁注。 – user472875 2012-04-25 19:17:55

+0

您可以将WHERE条件移至WITH查询,也可以将其删除几毫秒。 – Andrew 2012-04-25 21:59:36

回答

1
WITH attributes AS (
    SELECT a.value('(.)[1]', 'nvarchar(max)') AS attribute 
    FROM YourTable 
    CROSS APPLY YourXMLColumn.nodes('//path/to/attributes') AS N(a) 
) 
SELECT attribute, COUNT(attribute) 
FROM attributes 
GROUP BY attribute 

CROSS APPLY是喜欢能够加入XML作为表。 WITH是需要的,因为您不能在组子句中使用xml方法。

+0

感谢您的快速回复,我还没有时间尝试这个,但它看起来非常有前途。一旦我开始运行,我会让你知道的。 – user472875 2012-04-25 16:54:29

+0

我根据你的回答编辑了我的问题。看看你是否有机会。 – user472875 2012-04-25 19:02:16

0

这是一种获取属性数据的方法,您可以轻松使用它并减少需要通过主表的次数。

--create test data 
declare @tmp table (
    field1 varchar(20), 
    field2 varchar(20), 
    field3 varchar(20)) 

insert into @tmp (field1, field2, field3) 
values ('A', 'B', 'C'), 
    ('B', 'C', 'D') 

--convert the individual fields from seperate columns to one column 
declare @table table(
    field varchar(20)) 

insert into @table (field) 
select field1 from @tmp 
union all 
select field2 from @tmp 
union all 
select field3 from @tmp 

--run the group by and get the count 
select field, count(*) 
from @table 
group by field