【问题标题】:SQL Server OVER() clause not behaving as expectedSQL Server OVER() 子句未按预期运行
【发布时间】:2018-09-18 16:16:10
【问题描述】:

我正在使用OVER() 子句根据帐号和付款日期获取总付款。然后,我从当前余额中减去该运行总计,以确定每次交易完成后的余额

SELECT
    no_,
    amount,
    SUM(amount) OVER(PARTITION BY no_ ORDER BY effectiveDate DESC) AS RunningTotal,
    balance - (SUM(amount) OVER(PARTITION BY no_ ORDER BY effectiveDate DESC)) + amount AS CalculatedBalance,
    balance
FROM 
    c
WHERE 
    status != 'closed'
ORDER BY 
    no_

它适用于正数,但当金额字段为负数时,我会得到如下奇怪的输出:

所有负数都会发生这种情况,我检查了所有正数,它们都是正确的。我在网上查了一下,找不到 OVER() 不接受负数的原因

【问题讨论】:

    标签: sql sql-server-2012 window-functions


    【解决方案1】:

    你为什么要反过来计算?我希望逻辑更像这样:

    SELECT no_, amount,
           SUM(amount) OVER (PARTITION BY no_ ORDER BY effectiveDate ASC) AS RunningTotal,
           (balance + amount +
            SUM(amount) OVER (PARTITION BY no_ ORDER BY effectiveDate ASC)
           ) AS CalculatedBalance,
           balance
    FROM c
    WHERE status <> 'closed'
    ORDER BY no_;
    

    此外,由于balance 为负数,您希望添加金额而不是减去它们。

    【讨论】:

      【解决方案2】:

      我认为您应该了解 ROWS BETWEEN PRECEDING 子句。

      在窗框子句中,您指明窗框单位(ROWS 或 RANGE)和窗框范围(分隔符)。随着行 窗框单元,您可以将分隔符指定为三个之一 选项:

      ■■ UNBOUNDED PRECEDING 或 FOLLOWING,表示开头或结尾 分区,分别

      ■■ CURRENT ROW,明显代表当前行

      ■■ ROWS PRECEDING 或 FOLLOWING,表示前或后 n 行 当前,分别

      语法示例:

      对数据集中找到的日期进行分组的临时查询 (1..7..infinity)

      , DENSE_RANK() 
          OVER(PARTITION BY tbl.Account ORDER BY tbl.Date DESC)
          AS [calcDayRankdenseGroup]
      

      最终结果:

      select 
          cte.* 
          , SUM(cte.Amount) 
              OVER(PARTITION BY cte.Account ORDER BY cte.calcDayRankdenseGroup ASC
                  ROWS BETWEEN 7 PRECEDING and CURRENT ROW)
              AS [Amount_RunningTotalDaysLast7]
      from cteDateRankAdded cte
      order by Account, DATE DESC
      

      从我的测试数据返回的数据(如下所示):

      +---------+--------+------------+---------------------------+-----------------------+---------------------+------------------------------+
      | Account | Amount | DATE       | calcDayRankGroup_DoNotUse | calcDayRankdenseGroup | calcDayCountInGroup | Amount_RunningTotalDaysLast7 |
      +---------+--------+------------+---------------------------+-----------------------+---------------------+------------------------------+
      | 1       | 30.00  | 2018-09-16 | 1                         | 1                     | 1                   | 30.00                        |
      +---------+--------+------------+---------------------------+-----------------------+---------------------+------------------------------+
      | 1       | 69.00  | 2018-09-16 | 1                         | 1                     | 2                   | 99.00                        |
      +---------+--------+------------+---------------------------+-----------------------+---------------------+------------------------------+
      | 1       | 6.00   | 2018-09-13 | 3                         | 2                     | 1                   | 105.00                       |
      +---------+--------+------------+---------------------------+-----------------------+---------------------+------------------------------+
      | 1       | 57.00  | 2018-09-12 | 4                         | 3                     | 1                   | 162.00                       |
      +---------+--------+------------+---------------------------+-----------------------+---------------------+------------------------------+
      | 1       | 13.00  | 2018-09-12 | 4                         | 3                     | 2                   | 175.00                       |
      +---------+--------+------------+---------------------------+-----------------------+---------------------+------------------------------+
      | 1       | 98.00  | 2018-09-12 | 4                         | 3                     | 3                   | 273.00                       |
      +---------+--------+------------+---------------------------+-----------------------+---------------------+------------------------------+
      | 1       | 47.00  | 2018-09-03 | 7                         | 4                     | 1                   | 320.00                       |
      +---------+--------+------------+---------------------------+-----------------------+---------------------+------------------------------+
      | 1       | 90.00  | 2018-09-02 | 8                         | 5                     | 1                   | 410.00                       |
      +---------+--------+------------+---------------------------+-----------------------+---------------------+------------------------------+
      | 1       | 90.00  | 2018-09-02 | 8                         | 5                     | 2                   | 470.00                       |
      +---------+--------+------------+---------------------------+-----------------------+---------------------+------------------------------+
      | 1       | 32.00  | 2018-08-29 | 10                        | 6                     | 1                   | 433.00                       |
      +---------+--------+------------+---------------------------+-----------------------+---------------------+------------------------------+
      | 1       | 50.00  | 2018-08-24 | 11                        | 7                     | 1                   | 477.00                       |
      +---------+--------+------------+---------------------------+-----------------------+---------------------+------------------------------+
      | 1       | 48.00  | 2018-08-24 | 11                        | 7                     | 2                   | 468.00                       |
      +---------+--------+------------+---------------------------+-----------------------+---------------------+------------------------------+
      | 1       | 100.00 | 2018-08-23 | 13                        | 8                     | 1                   | 555.00                       |
      +---------+--------+------------+---------------------------+-----------------------+---------------------+------------------------------+
      | 1       | 63.00  | 2018-08-20 | 14                        | 9                     | 1                   | 520.00                       |
      +---------+--------+------------+---------------------------+-----------------------+---------------------+------------------------------+
      | 1       | 49.00  | 2018-08-19 | 15                        | 10                    | 1                   | 522.00                       |
      +---------+--------+------------+---------------------------+-----------------------+---------------------+------------------------------+
      | 2       | 38.00  | 2018-09-16 | 1                         | 1                     | 1                   | 38.00                        |
      +---------+--------+------------+---------------------------+-----------------------+---------------------+------------------------------+
      | 2       | 3.00   | 2018-09-16 | 1                         | 1                     | 2                   | 41.00                        |
      +---------+--------+------------+---------------------------+-----------------------+---------------------+------------------------------+
      | 2       | 83.00  | 2018-09-13 | 3                         | 2                     | 1                   | 124.00                       |
      +---------+--------+------------+---------------------------+-----------------------+---------------------+------------------------------+
      | 2       | 28.00  | 2018-09-12 | 4                         | 3                     | 1                   | 152.00                       |
      +---------+--------+------------+---------------------------+-----------------------+---------------------+------------------------------+
      | 2       | 78.00  | 2018-09-12 | 4                         | 3                     | 2                   | 230.00                       |
      +---------+--------+------------+---------------------------+-----------------------+---------------------+------------------------------+
      | 2       | 32.00  | 2018-09-12 | 4                         | 3                     | 3                   | 262.00                       |
      +---------+--------+------------+---------------------------+-----------------------+---------------------+------------------------------+
      | 2       | 29.00  | 2018-09-03 | 7                         | 4                     | 1                   | 291.00                       |
      +---------+--------+------------+---------------------------+-----------------------+---------------------+------------------------------+
      | 2       | 64.00  | 2018-09-02 | 8                         | 5                     | 1                   | 355.00                       |
      +---------+--------+------------+---------------------------+-----------------------+---------------------+------------------------------+
      | 2       | 81.00  | 2018-09-02 | 8                         | 5                     | 2                   | 398.00                       |
      +---------+--------+------------+---------------------------+-----------------------+---------------------+------------------------------+
      | 2       | 60.00  | 2018-08-29 | 10                        | 6                     | 1                   | 455.00                       |
      +---------+--------+------------+---------------------------+-----------------------+---------------------+------------------------------+
      | 2       | 82.00  | 2018-08-24 | 11                        | 7                     | 1                   | 454.00                       |
      +---------+--------+------------+---------------------------+-----------------------+---------------------+------------------------------+
      | 2       | 66.00  | 2018-08-24 | 11                        | 7                     | 2                   | 492.00                       |
      +---------+--------+------------+---------------------------+-----------------------+---------------------+------------------------------+
      | 2       | 9.00   | 2018-08-23 | 13                        | 8                     | 1                   | 423.00                       |
      +---------+--------+------------+---------------------------+-----------------------+---------------------+------------------------------+
      | 2       | 45.00  | 2018-08-20 | 14                        | 9                     | 1                   | 436.00                       |
      +---------+--------+------------+---------------------------+-----------------------+---------------------+------------------------------+
      | 2       | 43.00  | 2018-08-19 | 15                        | 10                    | 1                   | 450.00                       |
      +---------+--------+------------+---------------------------+-----------------------+---------------------+------------------------------+
      

      这是我为代表您的场景而创建的示例数据,今天是 2018 年 9 月 18 日。

      +-----+---------+------------+--------+------------------+------------------+
      | Seq | Account | DATE       | Amount | dataDaysAgoDelta | dataDaysAgoGroup |
      +-----+---------+------------+--------+------------------+------------------+
      | 1   | 1       | 2018-08-19 | 49.00  | 30               | 10               |
      +-----+---------+------------+--------+------------------+------------------+
      | 2   | 1       | 2018-08-20 | 63.00  | 29               | 9                |
      +-----+---------+------------+--------+------------------+------------------+
      | 3   | 1       | 2018-08-23 | 100.00 | 26               | 8                |
      +-----+---------+------------+--------+------------------+------------------+
      | 4   | 1       | 2018-08-24 | 50.00  | 25               | 7                |
      +-----+---------+------------+--------+------------------+------------------+
      | 5   | 1       | 2018-08-24 | 48.00  | 25               | 7                |
      +-----+---------+------------+--------+------------------+------------------+
      | 6   | 1       | 2018-08-29 | 32.00  | 20               | 6                |
      +-----+---------+------------+--------+------------------+------------------+
      | 7   | 1       | 2018-09-02 | 90.00  | 16               | 5                |
      +-----+---------+------------+--------+------------------+------------------+
      | 8   | 1       | 2018-09-02 | 90.00  | 16               | 5                |
      +-----+---------+------------+--------+------------------+------------------+
      | 9   | 1       | 2018-09-03 | 47.00  | 15               | 4                |
      +-----+---------+------------+--------+------------------+------------------+
      | 10  | 1       | 2018-09-12 | 57.00  | 6                | 3                |
      +-----+---------+------------+--------+------------------+------------------+
      | 11  | 1       | 2018-09-12 | 13.00  | 6                | 3                |
      +-----+---------+------------+--------+------------------+------------------+
      | 12  | 1       | 2018-09-12 | 98.00  | 6                | 3                |
      +-----+---------+------------+--------+------------------+------------------+
      | 13  | 1       | 2018-09-13 | 6.00   | 5                | 2                |
      +-----+---------+------------+--------+------------------+------------------+
      | 14  | 1       | 2018-09-16 | 30.00  | 2                | 1                |
      +-----+---------+------------+--------+------------------+------------------+
      | 15  | 1       | 2018-09-16 | 69.00  | 2                | 1                |
      +-----+---------+------------+--------+------------------+------------------+
      | 16  | 2       | 2018-08-19 | 43.00  | 30               | 10               |
      +-----+---------+------------+--------+------------------+------------------+
      | 17  | 2       | 2018-08-20 | 45.00  | 29               | 9                |
      +-----+---------+------------+--------+------------------+------------------+
      | 18  | 2       | 2018-08-23 | 9.00   | 26               | 8                |
      +-----+---------+------------+--------+------------------+------------------+
      | 19  | 2       | 2018-08-24 | 82.00  | 25               | 7                |
      +-----+---------+------------+--------+------------------+------------------+
      | 20  | 2       | 2018-08-24 | 66.00  | 25               | 7                |
      +-----+---------+------------+--------+------------------+------------------+
      | 21  | 2       | 2018-08-29 | 60.00  | 20               | 6                |
      +-----+---------+------------+--------+------------------+------------------+
      | 22  | 2       | 2018-09-02 | 64.00  | 16               | 5                |
      +-----+---------+------------+--------+------------------+------------------+
      | 23  | 2       | 2018-09-02 | 81.00  | 16               | 5                |
      +-----+---------+------------+--------+------------------+------------------+
      | 24  | 2       | 2018-09-03 | 29.00  | 15               | 4                |
      +-----+---------+------------+--------+------------------+------------------+
      | 25  | 2       | 2018-09-12 | 28.00  | 6                | 3                |
      +-----+---------+------------+--------+------------------+------------------+
      | 26  | 2       | 2018-09-12 | 78.00  | 6                | 3                |
      +-----+---------+------------+--------+------------------+------------------+
      | 27  | 2       | 2018-09-12 | 32.00  | 6                | 3                |
      +-----+---------+------------+--------+------------------+------------------+
      | 28  | 2       | 2018-09-13 | 83.00  | 5                | 2                |
      +-----+---------+------------+--------+------------------+------------------+
      | 29  | 2       | 2018-09-16 | 38.00  | 2                | 1                |
      +-----+---------+------------+--------+------------------+------------------+
      | 30  | 2       | 2018-09-16 | 3.00   | 2                | 1                |
      +-----+---------+------------+--------+------------------+------------------+
      

      完成查询:

      DECLARE @tblDaysLast7Found as table
          (Seq int, Account int, DATE date, Amount numeric(10,2), dataDaysAgoDelta int, dataDaysAgoGroup int)
      
      INSERT INTO @tblDaysLast7Found 
          (Seq, Account, DATE, Amount, dataDaysAgoDelta, dataDaysAgoGroup)
      VALUES
          (1, 1, '8/19/2018', 49, 30, 10)
          ,(2, 1,  '8/20/2018', 63, 29, 9)
          ,(3, 1,  '8/23/2018', 100, 26, 8)
          ,(4, 1,  '8/24/2018', 50, 25, 7)
          ,(5, 1,  '8/24/2018', 48, 25, 7)
          ,(6, 1,  '8/29/2018', 32, 20, 6)
          ,(7, 1,  '9/2/2018', 90, 16, 5)
          ,(8, 1,  '9/2/2018', 90, 16, 5)
          ,(9, 1,  '9/3/2018', 47, 15, 4)
          ,(10, 1, '9/12/2018', 57, 6, 3)
          ,(11, 1, '9/12/2018', 13, 6, 3)
          ,(12, 1, '9/12/2018', 98, 6, 3)
          ,(13, 1, '9/13/2018', 6, 5, 2)
          ,(14, 1, '9/16/2018', 30, 2, 1)
          ,(15, 1, '9/16/2018', 69, 2, 1)
          ,(16, 2, '8/19/2018', 43, 30, 10)
          ,(17, 2, '8/20/2018', 45, 29, 9)
          ,(18, 2, '8/23/2018', 9, 26, 8)
          ,(19, 2, '8/24/2018', 82, 25, 7)
          ,(20, 2, '8/24/2018', 66, 25, 7)
          ,(21, 2, '8/29/2018', 60, 20, 6)
          ,(22, 2, '9/2/2018', 64, 16, 5)
          ,(23, 2, '9/2/2018', 81, 16, 5)
          ,(24, 2, '9/3/2018', 29, 15, 4)
          ,(25, 2, '9/12/2018', 28, 6, 3)
          ,(26, 2, '9/12/2018', 78, 6, 3)
          ,(27, 2, '9/12/2018', 32, 6, 3)
          ,(28, 2, '9/13/2018', 83, 5, 2)
          ,(29, 2, '9/16/2018', 38, 2, 1)
          ,(30, 2, '9/16/2018', 3, 2, 1)
      
      --select * from @tblDaysLast7Found
      
      ;WITH cteDateRankAdded AS
      (
      select -- * 
          tbl.Account
          , tbl.Amount
          , tbl.DATE
          , RANK() 
              OVER(PARTITION BY tbl.Account ORDER BY tbl.Date DESC)
              AS [calcDayRankGroup_DoNotUse]
          , DENSE_RANK() 
              OVER(PARTITION BY tbl.Account ORDER BY tbl.Date DESC)
              AS [calcDayRankdenseGroup]
          , ROW_NUMBER() 
              OVER(PARTITION BY tbl.Account, tbl.Date ORDER BY tbl.Date DESC)
              AS [calcDayCountInGroup]
      from 
          @tblDaysLast7Found tbl
      )
      
      select 
          cte.* 
          , SUM(cte.Amount) 
              OVER(PARTITION BY cte.Account ORDER BY cte.calcDayRankdenseGroup ASC
                  ROWS BETWEEN 7 PRECEDING and CURRENT ROW)
              AS [Amount_RunningTotalDaysLast7]
      from cteDateRankAdded cte
      order by Account, DATE DESC
      

      【讨论】:

        猜你喜欢
        • 2018-10-07
        • 2012-12-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多