【问题标题】:SQL - Using CUBE grand total per rowSQL - 每行使用 CUBE 总计
【发布时间】:2020-10-27 02:10:08
【问题描述】:

这是我的代码:

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

我想在选定的框中将其更改为总计。如何编码或更改其上的字符串。

【问题讨论】:

  • 您编辑撤消了其他成员最近所做的改进。如果您检查编辑历史记录,您会看到他们是如何做到的。
  • 已经计算了每个品牌的总数,例如Apple: 170,000+70,000+170,000 = 410,000你能解释一下缺少哪个计算吗?此外,为了从您的问题中获得最佳结果,请提供“示例数据”和“预期结果”(但不是图像)。建议您查看页脚中的帮助链接,了解如何格式化以及如何最好地提问
  • @Used_By_Already 是的,每个品牌的总数已经计算过了,但我想更改每个品牌的总数。例如苹果的总数,我想将字符串值'Apple'更改为'Grand Total for apple'。
  • 我相信 with cube 已被弃用。

标签: sql sql-server


【解决方案1】:

如果您首先获取数据(上述数据的更简单版本),则可以将其用作数据源,根据需要进行转换/更新。

我在这里使用 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;

请注意,尽管 CUBE 通常在 SQL Server 中完成,如下所示 - 这意味着您可以选择通过哪些列进行 CUBE(或汇总等)

GROUP BY CUBE(MONTH(PurchaseDate), Brand)

重要更新在下面@MartinSmith 的评论之后

Martin Smith 建议我应该使用GROUPING 函数。在审查该函数时,他是 100% 正确的(感谢 Martin - 这是我今天学习的内容)。

作为参考,GROUPING 函数指示(用 1 或 0)该行是否为聚合行(例如,由 ROLLUP/CUBE/GROUPING SET 添加的行之一)。

我也犯了几个月的小计错误 - 把它放在错误的列中。

因此,更新应如下所示(另请注意,我还包括了来自 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;

【讨论】:

  • 我的问题解决了,非常感谢你的代码。对于最后一个问题,我如何取回“每月小计”?
  • 您可以在 CASE 表达式中添加另一行 - 我将使用附加行更新答案。
  • 你应该使用GROUPING函数
  • 我不知道@Martin 的那个功能 - 但是在阅读它时,我完全同意应该使用它。感谢您提供非常有用的反馈。我的答案已适当更新。
猜你喜欢
  • 2021-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多