【问题标题】:SQL Add Running Total Column for each item in a giant tableSQL为巨型表中的每个项目添加运行总列
【发布时间】:2014-10-29 17:40:39
【问题描述】:

我想根据 5 种交易类型(假设交易 A、B、C、D、E)计算运行总计。但是我在这个表中有超过一千种不同的产品,每个产品在不同的日子里可能有数百万条交易记录。

所以表格看起来像这样:

ProductID   A   B   C   D   E   Running Total

   1       10   0   5   0   5       20
   2       15   0   0   0   0       15
   3       20   5   0   10  0       35
   1       10   0   0   0   0       30 (20 for product 1, plus 10 for product 1 again)
   3       12   0   33  0   0       80 (35 for product 3, plus 45 for product 3 again)

【问题讨论】:

  • 你想要完成什么?插入新记录时是否需要计算运行总计?你控制代码吗?必须用 SQL 实现吗?可以使用触发器或字段过程吗?
  • 什么关系型数据库? MySQL? SQL SERVER? oracle?语法因运行总计而异。不管是哪一个,我敢打赌,我可以在此站点上为您的 RDBMS 找到一个运行总示例……使用over 语法的窗口集可能是您在 Oracle、DB2、SQL 服务器、mySQL 中的用户变量中所需要的。
  • 大家好,非常感谢你们的 cmets。我正在使用 SQL Server 2008,并且我正在尝试计算自几年前以来每种产品的运行总量。根据运行总量,我可以在我们的仓库中获得手头的数量并直观地监控一切。我希望这会使问题更清楚。再次感谢我感谢大家的时间和善意。

标签: sql cumulative-sum


【解决方案1】:

测试数据

DECLARE @TABLE TABLE (ProductID INT, A INT,  B INT,  C INT,  D INT,  E INT)  
INSERT INTO @TABLE VALUES
(1 ,10,   0,   5 ,  0 ,  5),  --     20
(2 ,15,   0,   0 ,  0 ,  0),  --     15
(3 ,20,   5,   0 ,  10,  0),  --     35
(1 ,10,   0,   0 ,  0 ,  0),  --     30 (20 for product 1, plus 10 for product 1 again)
(3 ,12,   0,   33,  0 ,  0)   --    80

查询

;WITH CTE AS
(
    select *
          ,ROW_NUMBER() OVER (PARTITION BY ProductID ORDER BY ProductID ASC) rn 
    from @TABLE  
)
SELECT ProductID 
      ,A 
      ,B
      ,C
      ,D
      ,E
      ,runningTotal
FROM CTE c
 cross apply (select sum(A+B+C+D+E) as runningTotal
                from CTE
                where rn <= c.rn
                  and ProductID = c.ProductID
              ) as rt

结果

╔═══════════╦════╦═══╦════╦════╦═══╦══════════════╗
║ ProductID ║ A  ║ B ║ C  ║ D  ║ E ║ runningTotal ║
╠═══════════╬════╬═══╬════╬════╬═══╬══════════════╣
║         1 ║ 10 ║ 0 ║  5 ║  0 ║ 5 ║           20 ║
║         1 ║ 10 ║ 0 ║  0 ║  0 ║ 0 ║           30 ║
║         2 ║ 15 ║ 0 ║  0 ║  0 ║ 0 ║           15 ║
║         3 ║ 20 ║ 5 ║  0 ║ 10 ║ 0 ║           35 ║
║         3 ║ 12 ║ 0 ║ 33 ║  0 ║ 0 ║           80 ║
╚═══════════╩════╩═══╩════╩════╩═══╩══════════════╝

【讨论】:

    【解决方案2】:

    ANSI标准方法是使用sum()作为窗口函数:

    select t.*,
           sum(a + b + c + d + e) over (partition by productid order by <datetimecol>) as RunningTotal
    from table t;
    

    SQL 表代表无序 集合,因此您需要一个指定排序的列。我猜想某处有一个日期/时间列用于此目的。

    大多数数据库都支持这种标准语法:Oracle、SQL Server 2012+、Postgres、Teradata 和 DB2。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-06
      • 2021-12-22
      • 1970-01-01
      相关资源
      最近更新 更多