【问题标题】:How to use SUM function in SQL with dynamic columns如何在带有动态列的 SQL 中使用 SUM 函数
【发布时间】:2018-07-16 13:02:31
【问题描述】:

我已将动态 PIVOT 的结果安排到临时表中,如下所示:

--------------------------------------------------------
| City        | 2018-07-14 | 2018-07-15  |  2018-07-16 |
--------------------------------------------------------
| Satara      |     3      |      9      |      1      |
| Maharashtra |     0      |      4      |      1      |
| Ghatkopar   |     10     |      1      |      1      |
--------------------------------------------------------

预期输出:

----------------------------------------------------------------------
| City        |  2018-07-14 | 2018-07-15 | 2018-07-16 |    Total     |
---------------------------------------------------------------------
| Satara      |   3         |     9      |      1     |      13      |
| Maharashtra |   0         |     4      |      1     |      5       |
| Ghatkopar   |   10        |     1      |      1     |      12      |
----------------------------------------------------------------------
 NULL         |   13        |     14    |      3      |      30      |
--------------------------------------------------------------------

最后三列是动态的日期Today's Date - 3 Days

【问题讨论】:

  • 您可能会在 PIVOT 之前为您的列 Total 进行更好的聚合,然后再进行旋转。否则,简单就是简单的数学:[2018-07-14]+[2018-07-15]+[2018-07-16] AS Total。我不能给你更多的细节,因为我没有你的 SQL,只有一些数据。
  • 垂直总计最重要
  • 添加垂直线的一种方法是在求和查询上与详细信息具有相同的枢轴的 UNION。
  • 但是那个日期是动态的——它会从 7 月 17 日到 7 月 15 日从明天开始改变
  • 是的,并且作为动态数据,这就是为什么我要为您的列 Total 聚合,然后是 PIVOT。不是PIVOT 和聚合。

标签: sql sql-server


【解决方案1】:

您可以使用 GROUP BY ROLLUP 来获取垂直总计。在此示例中,我将 Total 计算为计算列,但您可以改为在数据透视之前进行聚合。

DECLARE @tbl TABLE (City VARCHAR(25), [2018-07-14] int, [2018-07-15] int, 
    [2018-07-16] int, Total AS [2018-07-14] + [2018-07-15] + [2018-07-16])

INSERT INTO @tbl VALUES ('Satara', 3, 9, 1)
INSERT INTO @tbl VALUES ('Maharashtra', 0, 4, 1)
INSERT INTO @tbl VALUES ('Ghatkopar', 10, 1, 1)

SELECT City, SUM([2018-07-14]) AS [2018-07-14], 
    SUM([2018-07-15]) AS [2018-07-15], 
    SUM([2018-07-16]) AS [2018-07-16],
    SUM(Total) AS Total
FROM @tbl
GROUP BY ROLLUP (City);

返回:

City        2018-07-14  2018-07-15  2018-07-16  Total
Ghatkopar   10          1           1           12
Maharashtra 0           4           1           5
Satara      3           9           1           13
NULL        13          14          3           30

如果您担心动态列标题,可以使用动态 sql 以编程方式更改它们:

DECLARE @D1 VARCHAR(10) = FORMAT(GETDATE() - 2, 'yyyy-MM-dd')
DECLARE @D2 VARCHAR(10) = FORMAT(GETDATE() - 1, 'yyyy-MM-dd')
DECLARE @D3 VARCHAR(10) = FORMAT(GETDATE(), 'yyyy-MM-dd')

DECLARE @SQL NVARCHAR(MAX)
SELECT @SQL = '
SELECT City, SUM([' + @D1 + ']) AS [' + @D1 + '], 
    SUM([' + @D2 + ']) AS [' + @D2 + '], 
    SUM([' + @D3 + ']) AS [' + @D3 + '],
    SUM([' + @D1 + '] + [' + @D2 + '] + [' + @D3 + ']) AS Total
FROM tbl
GROUP BY ROLLUP (City);'

EXEC sp_executesql @SQL

【讨论】:

  • 感谢您的回复!当我使用单列 ROLLUP 进行测试时,它工作正常,但我在 select 中有多个列,例如 contact_number,所以按它们分组会产生不正确的结果
  • 查看 GROUP BY GROUPING SETS!
  • @PrashantPimpale 如果你想按多列汇总,GROUP BY ROLLUP ((City, ContactNumber));不过,请确保包含第二组括号;这会将它们组合为一个分组集。如果您执行 GROUP BY ROLLUP (City, ContactNumber),它将按城市分组为一个分组集,然后将 ContactNumber 作为第二个分组集。
  • 还有 2 列,包括城市,如 ContactNumberName 所以如果我使用分组,那么数据就会重复
  • 如果你能在this帮助我,我会非常有帮助
猜你喜欢
  • 2019-09-01
  • 1970-01-01
  • 2012-10-23
  • 2021-06-30
  • 2016-09-03
  • 2013-09-14
  • 2018-05-17
  • 1970-01-01
  • 2020-06-05
相关资源
最近更新 更多