我有一个包含分组列和数字列的表,我想总结一下。我的表看起来像这样:
Person Object Count
-------- --------- -------
John apples 1
John pears 6
John ferrari 10
Mike porsche 3
Mike ferrari 1
我想创建一个每人返回一行的表,并返回包含一组对象的多个列。在这个例子中,苹果和梨都是水果和法拉利,而保时捷都是汽车。我的结果表看起来像这样:
Person Fruits Cars
-------- -------- ------
John 7 10
Mike 0 4
我有一个帮助表,可以将每个对象分配给一个组。组的数量是一成不变的,但我可能会在每组中添加更多对象。这就是我创建这个帮助表的原因,这样当我的数据中有新对象时,我可以简单地添加一行。例如,我可能稍后添加李子(也是水果)或丰田(也是汽车),但我绝不会添加任何不是汽车或水果的东西。
Object Group
--------- --------
apples fruits
pears fruits
ferrari cars
porsche cars
我的解决方案是以下查询:
SELECT
Person,
SUM(CASE WHEN Object IN (SELECT Object FROM help_table WHERE Group = 'fruits') THEN Count END) AS Fruits,
SUM(CASE WHEN Object IN (SELECT Object FROM help_table WHERE Group = 'cars') THEN Count END) AS Cars
FROM start_table
GROUP BY Person
它返回以下错误:
Cannot perform an aggregate function on an expression containing an aggregate or a subquery.
我正在寻找其他解决方案以达到预期效果。在查询中可以很容易地指定哪些对象属于每个组,但我真的更喜欢将新对象添加到表中,而不必对其进行硬编码。
答案 0 :(得分:1)
这适用于一组有限的小组
SELECT
Person,
COUNT(hf.Object),
COUNT(hc.Object)
FROM
start_table s
LEFT join
help_table hf ON s.Object = hf.Object AND hf.Group = 'fruits'
LEFT join
help_table hc ON s.Object = hc.Object AND hc.Group = 'cars'
GROUP BY Person
每组添加一个新列会变得更加棘手,因为SQL并不真正支持任意列输出
答案 1 :(得分:1)
创建两个表,水果和汽车:
SELECT
s.Person,
sum(fruits.count) as Fruits,
sum(cars.count) AS Cars
FROM start_table s
left join help_table fruits on s.[Object] = fruits.[Object] and fruits.[Group] = 'fruits'
left join help_table cars on s.Object = cars.Object and cars.[Group] = 'cars'
GROUP BY s.Person
答案 2 :(得分:1)
您可以使用sum和pivot如下:
Select * from (
Select [Person], [Group], sum([Count]) as sm from start_table s
left join help_table h
on s.[Object] = h.[Object]
group by [Person], [Group]
) a
pivot (sum(sm) for [Group] in ([fruits],[cars])) p
对于[Group]的动态列表,您可以查询如下
Declare @cols1 varchar(max)
Declare @query nvarchar(max)
Select @cols1 = stuff((select distinct ','+QuoteName([Group]) from help_table for xml path('')),1,1,'')
Set @query = ' Select * from (
Select [Person], [Group], [Count] from start_table s
left join help_table h
on s.[Object] = h.[Object]
) a
pivot (sum([Count]) for [Group] in (' + @cols1 + ')) p '
Exec sp_executesql @query
答案 3 :(得分:0)
您可以使用公用表表达式轻松获得此功能。下面的查询将给出所需格式的结果。我还在here创建了一个sqlfiddle。有时SqlFiddle无法正确加载,请在链接上重试。请随便看看。
SELECT
Person,
ISNULL(Cars, 0) Cars,
ISNULL(Fruits, 0) Fruits
FROM (SELECT
Person,
[Group],
SUM([Count]) AS TotalCount
FROM Userdata
JOIN ItemGroup
ON ItemGroup.Item = Userdata.Item
GROUP BY Person,
[Group]) x
PIVOT
(
SUM(TotalCount)
FOR [Group] IN ([fruits], [cars])
) pvt