【问题标题】:Sum one column and subtract over second column将一列相加并减去第二列
【发布时间】:2018-10-24 18:08:16
【问题描述】:

我想显示两列的减法。从第一列中,我需要对所有值求和,然后从第二列中减去每个值。

这是表结构:

id | name | col1  | col2 | date
------------------------------------
432| xxx  | 0     | 15   |2015-11-17
432| yyy  | 10    | 30   |2015-11-19 
432| zzz  | 60    | 40   |2015-11-20  

433| aaa  | 0     | 60   |2015-11-17
433| bbb  | 80    | 20   |2015-11-19 
433| ccc  | 60    | 10   |2015-11-20  

公式应该去:

sum(col1) = 70  =>>>   WHERE ID = 432  

70 - col2            col3
-------------------------
=> 70 - 15         =  55
=> 70 - (30 + 15)  =  25 
=> 70 - (40 + 45)  = -15
---------------------------

sum(col1) = 140  ===>>    WHERE ID = 433  

 140 -   col2         col3
-------------------------
=> 140 -  60        =  80
=> 140 - (60 + 20)  =  60 
=> 140 - (10 + 80)  =  50

结果是 col3 并且输出应该像 as

id | name | col1  | col2 | col3 |    date
-------------------------------------------
432| xxx  | 0     | 15   |  55  |  2015-11-17
432| yyy  | 10    | 30   |  25  |  2015-11-19 
432| zzz  | 60    | 40   | -15  |  2015-11-20  

433| aaa  | 0     | 60   |  80  |  2015-11-17
433| bbb  | 80    | 20   |  60  |  2015-11-19 
433| ccc  | 60    | 10   |  50  |  2015-11-20 

编辑:如果我需要的值会根据组作为 432 和 433 id 列而有所不同。

【问题讨论】:

    标签: sql-server tsql sql-server-2014


    【解决方案1】:

    架构信息

    DECLARE @TEST TABLE
      (
         id INT,
         name VARCHAR(10),
         col1       INT,
         col2        int
      ) 
    
    INSERT INTO @TEST VALUES 
    (432,'xxx',0, 15 ),
    (432,'yyy',10, 30 ),
    (432,'zzz',60, 40 ),
    (433,'aaa',0, 60 ),
    (433,'bbb',80, 20 ),
    (433,'ccc',60, 10 )
    

    查询

        SELECT  T.id ,
            T.name ,
            T.col1 ,
            T.col2 ,
            SUM(T.col1) OVER( PARTITION BY T.id ORDER BY T.id ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
            - SUM(T.col2) OVER ( PARTITION BY T.id ORDER BY T.id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS col3
    FROM    @TEST T;
    

    结果

    id | name | col1  | col2 | col3 |
    ---------------------------------
    432  | xxx  | 0     | 15   |  55  |
    432  | yyy  | 10    | 30   |  25  |
    432  | zzz  | 60    | 40   | -15  |
    433  | aaa  | 0     | 60   |  80  | 
    433  | bbb  | 80    | 20   |  60  | 
    433  | ccc  | 60    | 10   |  50  | 
    

    SQL Fiddle

    【讨论】:

    • @sqlProfile87:那么您必须对我的查询使用 partition by 子句。等等,我会在几分钟内更新我的答案
    • @sqlProfile87:我已经更新了我的答案。检查 sql fiddle 链接的结果
    【解决方案2】:

    这应该可行:

    declare @total int = (select sum(col1) from Table)
    select id, name, col1, col2, @total - (select sum(col2) from Table where date <= T.date) as col3, date from Table T
    

    我假设您想每次减去前一个总数(基于日期)。我希望这没问题。

    【讨论】:

    • 我建议使用 id 字段而不是日期。如果您有两行具有相同的日期...
    • @JoeTaras 这真的取决于他需要什么。同一日期应该不是问题。
    【解决方案3】:

    您可以使用简单的选择查询和交叉应用

        SELECT ID
        ,NAME
        ,COL1
        ,COL2
        ,A.C1 - (
            SUM(COL2) OVER (
                ORDER BY ID
                )
            ) AS COL3
    FROM TABLE1 T1
    CROSS APPLY (
        SELECT SUM(COL1) AS C1
        FROM TABLE1 T2
        ) A
    

    【讨论】:

      【解决方案4】:

      您可以在 SELECT 字段列表中使用两个子查询。

      在第一个中,您将获得名为 yourtable 的表中所有行的总和,在第二个中,您将获得当前行之前的所有行的总和。所以你可以减去两个值。

      试试这个:

      SELECT T.id, T.name, T.col1, T.col2,
      ISNULL(
          (SELECT SUM(T2.col1) FROM yourtable T2)
      ,0) - 
      ISNULL(
          (SELECT SUM(T3.col2) FROM yourtable T3 
          WHERE T3.id <= T.id)
      ,0) as col3,
      t.date
      FROM yourtable T
      

      继续Sql fiddle example

      编辑

      SELECT T.id, T.name, T.col1, T.col2,
      ISNULL(
          (SELECT SUM(T2.col1) FROM yourtable T2 where T2.id = T.id)
      ,0) - 
      ISNULL(
          (SELECT SUM(T3.col2) FROM yourtable T3 
          WHERE T3.id = T.id AND T3.date <= T.date)
      ,0) as col3,
      t.date
      FROM yourtable T
      

      继续Sql Fiddle edited example

      注意:深度编辑可能是一个不同的问题。两个查询是不同的

      注意:名称为ID的字段不能重复值

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-10
        • 1970-01-01
        相关资源
        最近更新 更多