帮助SQL - 分组依据和多个聚合

时间:2010-12-13 11:24:45

标签: tsql sql-server-2008 grouping

我有一个客户表和一个orderdetail表 客户ID是orderdetail表中的foriegn键(我在这里简化)

orderdetail表包含以下列 的OrderId 项目Id 顾客ID 大小

“大小”列可以采用以下任何一个值 lr 2. md 3. sm

所以orderdetail表可能有以下记录(我用逗号分隔了列)

OrderId ItemId CustomerId Size

1,1,30,lr
1,1,30,md
1,1,30,sm
2,1,30,lr
2,1,30,md
3,1,30,lr
3,1,30,sm
4,1,30,lr
5,1,30,md
6,2,30,sm
7,3,30,md
8,3,30,lr

我想要的是一个非常有效的查询(订单详细信息表中有数百万条记录),它具有给定customerId的以下输出(在这种情况下为30)

ItemId  SizeLr  SizeMd  SizeSm
1         4       3        2
2         0       0        1
3         1       1        0

我正在使用的查询使用3组查询(“lr”,“md”和“sm”各一个),因此它会扫描表3次。

我正在寻找一种只扫描桌子的解决方案。我认为该解决方案是在MSSQL 2008中使用新的分组集功能。但无论哪种方式,如果我希望有人可以帮助我,使用一次扫描的解决方案。

修改

实际输出还需要来自customer表和订单详细信息表的其他字段。这些其他字段不依赖于聚合。

例如

ItemName  ItemId  SizeLr  SizeMd  SizeSm
   A         1      4       3       2
   B         2      0       0       1
   C         3      1       1       0
   Totals           5       4       4

如果我能够获得每个Size列的总数

,那就太好了

2 个答案:

答案 0 :(得分:1)

这个怎么样:

SELECT ItemId, 
    SUM(CASE WHEN Size = 'Lr' THEN 1 ELSE 0 END) AS SizeLr,
    SUM(CASE WHEN Size = 'Md' THEN 1 ELSE 0 END) AS SizeMd,
    SUM(CASE WHEN Size = 'Sm' THEN 1 ELSE 0 END) AS SizeSm
FROM OrderDetail 
WHERE CustomerId = 30
GROUP BY ItemId

答案 1 :(得分:1)

试试这个:

select Itemid,
    sum (case when Size = 'lr' then 1 else 0 end) SizeLR,
    sum (case when Size = 'Md' then 1 else 0 end) SizeMd,
    sum (case when Size = 'SM' then 1 else 0 end) SizeSM
from orderdetail 
group by Itemid
order by Itemid;    

如果ItemName依赖于ItemId,您可以这样做:

select Itemname, Itemid,
    sum (case when Size = 'lr' then 1 else 0 end) SizeLR,
    sum (case when Size = 'Md' then 1 else 0 end) SizeMd,
    sum (case when Size = 'SM' then 1 else 0 end) SizeSM
from orderdetail 
group by Itemid, Itemname
order by Itemid;