按计数列过滤

时间:2013-09-19 03:11:23

标签: sql tsql sql-server-2008-r2

ProductGroup

ProductGroupID  Description  
301             Shampoo         
302             Soap
303             Brush

产品

ProductID   ProductGroupID   Desc        Price
4001        301              Shampoo1    2
4002        301              Shampoo2    3 
4003        301              Shampoo3    4
4004        302              Soap1       2
4005        302              Soap2       3
4006        302              Soap3       5
4007        303              Brush1      6 
4008        303              Brush2      7
4009        303              Brush3      8

顺序

OrderID     ProductID  
50001       4001 
50002       4002 
50003       4002 
50004       4002 
50005       4003 
50006       4007 
50007       4009 
50008       4003 
50009       4001 
50010       4005 
50011       4008 
50012       4009 

不过滤

Select p.ProductID, p.Desc, pg.ProductGroupID, pg.Description  Count(o.ProductID) as OrderNum, p.Price
From Order o
inner join Product p
ON o.ProductID = p.ProductID
inner join ProductGroup pg
ON p.ProductGroupID = pg.ProductGroupID
Group By p.ProductID, p.Desc, pg.ProductGroupID, pg.Description, p.Price with Cube
Having ProductGroupID is not null 

ProductID  Desc        ProductGroupID  Description OrderNum   Price
4001       Shampoo1    301             Shampoo     2          2
4002       Shampoo2    301             Shampoo     3          3
4003       Shampoo3    301             Shampoo     2          4
--------   --------    301             Shampoo     7          ----
4004       Soap1       302             Soap        0          2
4005       Soap2       302             Soap        1          3
4006       Soap3       302             Soap        0          5
--------   --------    302             Brush       1          ----
4007       Brush1      303             Brush       1          6
4008       Brush2      303             Brush       1          7
4009       Brush3      303             Brush       2          8
--------   --------    303             Brush       4          ----

过滤小计

Select p.ProductID, p.Desc, pg.ProductGroupID, pg.Description  Count(o.ProductID) as OrderNum, p.Price
From Order o
inner join Product p
ON o.ProductID = p.ProductID
inner join ProductGroup pg
ON p.ProductGroupID = pg.ProductGroupID
Group By p.ProductID, p.Desc, pg.ProductGroupID, pg.Description, p.Price with Cube
Having ProductGroupID is not null 
AND SubTotal(OrderNum) =>  4 -- not working

ProductID  Desc        ProductGroupID  Description OrderNum   Price
4001       Shampoo1    301             Shampoo     2          2
4002       Shampoo2    301             Shampoo     3          3
4003       Shampoo3    301             Shampoo     2          4
--------   --------    301             Shampoo     7          ----
4007       Brush1      303             Brush       1          6
4008       Brush2      303             Brush       1          7
4009       Brush3      303             Brush       2          8
--------   --------    303             Brush       4          ----

我将如何过滤小计?

2 个答案:

答案 0 :(得分:2)

根据您想要的小计,您可以使用ROLLUPCUBE运算符。

Rollup会给你一个小计的层次结构。 (我假设ProductIDDesc具有1:1匹配,因此我在汇总中将它们连接起来,对于组ID和描述也是如此。我还假设你可能想要在产品组中分组的产品。

GROUP BY ROLLUP((pg.ProductGroupID, pg.Description), (p.ProductID, p.Desc), p.Price)

或者您可以使用立方体运算符来获取所有可能的总计和小计。

GROUP BY p.ProductID, p.Desc, pg.ProductGroupID, pg.Description, p.Price WITH CUBE

您还可以使用GROUP BY GROUPING SETS(...手动指定所需的所有分组。

还有其他例子here

答案 1 :(得分:1)

看起来您正在尝试过滤聚合值。 1.使用HAVING代替最后WHERE子句:

Select p.ProductID, p.Desc, pg.ProductGroupID, pg.Description  Count(o.ProductID) as OrderNum, p.Price
From Order o
inner join Product p
ON o.ProductID = p.ProductID
inner join ProductGroup pg
ON p.ProductGroupID = pg.ProductGroupID
Group By p.ProductID, p.Desc, pg.ProductGroupID, pg.Description, p.Price
HAVING COUNT(OrderNum) =>  4

由于这是针对SQL 2008 R2的,因此您可以使用WITH CUBE来获取小计:

Select 
    p.ProductID, 
    p.[Desc], 
    pg.ProductGroupID, 
    pg.Description, 
    Count(o.ProductID) as OrderNum, 
    p.Price
From 
    Order o
    inner join Product p ON o.ProductID = p.ProductID
    inner join ProductGroup pg ON p.ProductGroupID = pg.ProductGroupID
Group By 
    p.ProductID, 
    p.[Desc], 
    pg.ProductGroupID, 
    pg.Description, 
    p.Price
with cube

要根据某个过滤器值抓取特定部分,您可以执行此操作:

SELECT * 
FROM 
    (
        Select 
            p.ProductID, 
            --p.[Desc], 
            --pg.ProductGroupID, 
            pg.Description, 
            Count(o.ProductID) as OrderNum, 
            p.Price
        From 
            Order o
            inner join Product p ON o.ProductID = p.ProductID
            inner join ProductGroup pg ON p.ProductGroupID = pg.ProductGroupID
        Group By 
            p.ProductID, 
            --p.[Desc], 
            --pg.ProductGroupID, 
            pg.Description, 
            p.Price
        with cube
    ) subTotals
    inner join 
    (
        SELECT Count(o.ProductID) as OrderNum, pg.Description
        FROM 
            Order o
            inner join Product p ON o.ProductID = p.ProductID
            inner join ProductGroup pg ON p.ProductGroupID = pg.ProductGroupID
        GROUP BY pg.Description
        HAVING Count(o.ProductID) >= 4
    ) groupFilter on groupFilter.Description = subTotals.description 
where Price IS NULL