动态列表上的T-SQL GROUP BY

时间:2012-04-25 16:10:41

标签: tsql

我有一个带有XML类型列的表。此列包含记录之间可能不同的动态属性列表。

我正在尝试对这些属性进行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

作为旁注:有没有办法进一步减少这种情况?

2 个答案:

答案 0 :(得分: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方法。

答案 1 :(得分: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