按组小计

时间:2015-10-21 03:04:47

标签: sql-server tsql

我有这样的数据:

SaleID    ParentCo    Subsidiary      Amount
1         BigCo       Big A LTD       10
2         MedCo       Medium Inc.     10
3         BigCo       BigCo Corp.     10
4         BigCo       Biggest Co.     10
5         BigCo       Big A LTD       10
6         MedCo       Medium LLC      10
7         MedCo       Medium Inc.     10
8         SmallCo     SmallCo         10

我想显示每个ParentCo和每个子公司的总数,由ParentCo订购DESC并且由子公司分组和订购(这是一个单词?),如下所示:

ParentCo     Subsidiary    SumOfAmount
BigCo        (all)         40
BigCo        Big A LTD     20
BigCo        BigCo Corp    10
BigCo        Biggest Co.   10
MedCo        (all)         30
MedCo        Medium Inc.   20
MedCo        Medium LLC    10
SmallCo      (all)         10
SmallCo      SmallCo       10

我得到的最远的是:

SELECT [ParentCo], [Subsidiary], SUM([Amount]) AS SumOfAmount FROM [table]
GROUP BY [ParentCo], [Subsidiary]
WITH ROLLUP
ORDER BY SumOfAmount DESC;

但是,任何知道任何事情的人都会看到,这不起作用,因为它显示SumofAmount下降的所有行,而不保持每个子公司的总数在下面(或者就此而言,在其上方或旁边)对齐其总数母公司。

我在想我可能需要某种嵌套查询,但是,我是一个菜鸟,上面是我写过的最复杂的SQL。

如果它更容易,我也可以在不同的列中显示子公司和父母的总和,重复每个子公司旁边的父母总和:

ParentCo     Subsidiary    SumOfSubsidiary   SumOfParent
BigCo        Big A LTD     20                40
BigCo        BigCo Corp    10                40
BigCo        Biggest Co.   10                40
MedCo        Medium Inc.   20                30
MedCo        Medium LLC    10                30
SmallCo      SmallCo       10                10

虽然我们在这,但是一个相关的问题:

有没有办法只显示每个ParentCo的总数,但在它旁边,显示其子公司的名称和小计,具有最大的小计,如下所示:

ParentCo     SumOfParent    LargestSubsidiary  SumOfSubsidiary  
BigCo        40             Big A LTD          20
MedCo        30             Medium Inc.        20
SmallCo      10             SmallCo            10

有什么想法吗?提前谢谢!

2 个答案:

答案 0 :(得分:1)

您可以使用CTESUM OVER()结合来实现所需的排序:

WITH Cte AS(
    SELECT
        ISNULL(ParentCo, 'ALL') AS ParentCo,
        ISNULL(Subsidiary, 'ALL') AS Subsidiary,
        SUM(Amount) AS SumOfAmount
    FROM tbl
    GROUP BY 
        ParentCo, Subsidiary
    WITH ROLLUP
),
CteFinal AS(
    SELECT *,
        sm = SUM(SumOfAmount) OVER(PARTITION BY ParentCo)
    FROM Cte
    WHERE
        ParentCo <> 'ALL'
)
SELECT
    ParentCo, Subsidiary, SumOfAmount
FROM CteFinal
ORDER BY
    sm DESC, SumOfAmount DESC

关于第二个问题,您只需使用SUM OVER()

即可
SELECT *,
    SumOfAmount = SUM(Amount) OVER(PARTITION BY ParentCo)
FROM tbl

答案 1 :(得分:1)

要获得第一个结果集,您还可以使用此查询:

SELECT 
    ParentCo, 
    CASE WHEN GROUPING(Subsiduary) = 1 THEN '(all)' ELSE Subsiduary END AS Subsiduary, 
    SUM(Amount) AS SumOfAmount
FROM 
    [table]
GROUP BY 
    ParentCo, 
    ROLLUP(Subsiduary)
ORDER BY 
    ParentCo, 
    Subsiduary