简体   繁体   English

SQL - 每行使用 CUBE 总计

[英]SQL - Using CUBE grand total per row

Here is my code:这是我的代码:

SELECT
    ISNULL (CONVERT(VARCHAR, MONTH(PurchaseDate)), NULL) [Month],
    ISNULL (Brand, CASE 
                      WHEN MONTH(PurchaseDate) IS NOT NULL THEN 'Monthly SubTotal'
                      WHEN Brand IS NULL THEN 'Grand Total'
                      ELSE 'N/A'
                   END) [Brand], SUM(Price) [Total Amount]
FROM 
    [dbo].[Purchase_Items] 
GROUP BY 
    MONTH(PurchaseDate), Brand WITH CUBE

I want to change it to Grand Total on selected box.我想在选定的框中将其更改为总计。 How to code it or change the string on it.如何对其进行编码或更改其上的字符串。

If you first get your data (a simpler version of what you have above) you can then use that as a data source to do conversions/updates as needed.如果您首先获取数据(上述数据的更简单版本),则可以将其用作数据源以根据需要进行转换/更新。

I'm using a CTE here, but you can do it with subqueries just as well.我在这里使用 CTE,但您也可以使用子查询来实现。

WITH MonthTotals AS
    (SELECT
       MONTH(PurchaseDate) [Month],
       [Brand],
       SUM(Price) [Total Amount]
    FROM [dbo].[Purchase_Items] 
    GROUP BY MONTH(PurchaseDate), Brand WITH CUBE
    )
SELECT CONVERT(VARCHAR(2), mt.[Month]) AS [Month],
       CASE WHEN mt.[Month] IS NULL AND mt.[Brand] IS NULL THEN 'Grand Total'
            WHEN mt.[Month] IS NULL THEN 'Grand total for ' + mt.[Brand]
            WHEN mt.[Brand] IS NULL THEN 'Monthly total'
            ELSE mt.[Brand] END AS [Brand]
       [Total Amount]
  FROM MonthTotals mt;

Note though that CUBE is usually done in SQL Server like the following - it means you can select which columns you CUBE by (or rollup, etc)请注意,虽然 CUBE 通常在 SQL Server 中完成,如下所示 - 这意味着您可以选择 CUBE 的列(或汇总等)

GROUP BY CUBE(MONTH(PurchaseDate), Brand)

IMPORTANT UPDATE following @MartinSmith's comment below以下@MartinSmith 评论后的重要更新

Martin Smith gave the advice that I should use the GROUPING function. Martin Smith 建议我应该使用GROUPING函数。 In reviewing that function, he is 100% correct (and thankyou Martin - this is my learning for today).在查看该函数时,他 100% 正确(感谢 Martin - 这是我今天的学习内容)。

For reference, the GROUPING function indicates (with a 1 or 0) whether the row is an aggregate row or not (eg, one of the rows added by ROLLUP/CUBE/GROUPING SETs).作为参考,GROUPING 函数指示(用 1 或 0)该行是否为聚合行(例如,由 ROLLUP/CUBE/GROUPING SET 添加的行之一)。

I also made a mistake with subtotals for months - put it in the wrong column.几个月来,我在小计方面也犯了一个错误——把它放在错误的列中。

Therefore, the update should be the following (note also that I have included the 'original' vales from the CUBE for month and brand as well)因此,更新应如下(另请注意,我还包括了来自 CUBE 的月份和品牌的“原始”值)

WITH MonthTotals AS
    (SELECT
       MONTH(PurchaseDate) [Month],
       [Brand],
       SUM(Price) [Total Amount],
       GROUPING(MONTH(PurchaseDate)) AS Agg_flag_Month,
       GROUPING([Brand]) AS Agg_flag_Brand
    FROM [dbo].[Purchase_Items] 
    GROUP BY CUBE(MONTH(PurchaseDate), Brand)
    )
SELECT  [Month] AS Orig_Month,
        [Brand] AS Orig_Brand,
        CASE WHEN Agg_flag_Month = 1 THEN 'Grand total for ' + mt.[Brand]
            ELSE CONVERT(VARCHAR(2), mt.[Month]) 
            END AS [Month],
       CASE WHEN Agg_flag_Month * Agg_flag_Brand = 1 THEN 'Grand Total'
            WHEN Agg_flag_Brand = 1 THEN 'Monthly total'
            ELSE mt.[Brand] 
            END AS [Brand],
       [Total Amount]
  FROM MonthTotals mt;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM