SQL Server OVER()子句的行为不符合预期

SQL Server OVER()子句的行为不符合预期,sql,sql-server-2012,window-functions,Sql,Sql Server 2012,Window Functions,我正在使用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

我正在使用
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_
它适用于正数,但当amount字段为负数时,我会得到如下奇怪的输出:


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

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

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_;
选择否、金额、,
总计(按无订单划分,按生效日期ASC划分)作为运行总计,
(余额+金额)+
总额(金额)超过(按无订单划分,按生效日期ASC划分)
)作为计算余额,
平衡
来自c
何处状态为“关闭”
不可撤销的命令;

此外,由于
余额
为负数,您希望将金额相加,而不是相减。

我认为您应该了解前面的
子句之间的

在window frame子句中,指定窗框单位(行) 或范围)和窗口边框范围(分隔符)。排成一排 窗口帧单位,可以将分隔符指示为三个分隔符之一 选项:

■■ 无界的在前面或后面,意思是开始或结束 分别是分区

■■ 当前行,显然代表当前行

■■ 前面或后面的行,表示前面或后面的n行 分别为当前

语法示例:

临时查询,对数据集中的天数进行分组(1..7..无穷大)

最终结果:

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年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
+-----+---------+------------+--------+------------------+------------------+
| 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