SQL Server运行总计以具有365天的开窗功能根据美元金额查找帐户

时间:2018-08-27 20:02:54

标签: sql sql-server

我的问题。我需要运行每日报告,以查找自报告运行之日起的365个期间内支付了10,000美元或以上的帐户。我需要一个查询,该查询可以获取付款信息​​并为每个帐户进行总计,并且如果任何帐户在365窗口内的付款总额达到或超过10,000美元,则查询将返回达到阈值的日期或帐户号,我可以与任何一个一起工作。

到目前为止,这是我查询中适用的部分,但无法正常运行。我基于另一个查询,该查询通过从当前余额中减去付款来达到类似的目的。我以为可以对其进行修改以使其正常工作,但是没有成功。重要的是要注意,我尚未应用365过滤器。我试图确保查询的基本部分首先生效,然后再增加复杂性。我正在使用SQL Server 2014。

CREATE TABLE #PaymentDate
(number int,
paymentdate date,
balance money)


;
WITH Balances1 AS
(
    SELECT *,
        SUM(TotalPaid) OVER (PARTITION BY number, DatePaid ORDER BY 
DatePaid, number) AS Balance
    FROM #Accounts
)
, Balances2 AS
(
    SELECT *, ISNULL(LAG(Balance) OVER (PARTITION BY number, DatePaid ORDER 
BY DatePaid, number), 0) AS Prev
    FROM Balances1
)
INSERT INTO #PaymentDate
SELECT number, DatePaid, balance
FROM Balances2
WHERE Balance >= 10000 AND Prev < 10000
;

无法正确添加或忽略一次符合条件的一次性付款的帐户。

一些样本数据。该查询应返回前3个帐户,因为它们在365天的窗口内(今天的日期为18/8/27)总共有10,000或更多的付款。不应包含第4个帐户,因为它需要365天以上才能支付10,000或更多的款项:

Number  DatePaid    TotalPaid
123456  2017-12-01  12184.46
654321  2018-02-28  10000
231645  2017-05-31  3390
231645  2017-06-29  1565.29
231645  2017-07-26  1565.29
231645  2017-08-28  1565.29
231645  2017-09-28  1565.29
231645  2017-10-27  1565.29
231645  2017-12-01  6783.55
312546  2016-08-01  550
312546  2016-09-06  500
312546  2016-10-04  500
312546  2016-11-07  500
312546  2016-12-06  500
312546  2017-01-04  500
312546  2017-02-08  500
312546  2017-03-07  500
312546  2017-04-10  500
312546  2017-05-09  500
312546  2017-06-07  500
312546  2017-07-05  500
312546  2017-08-07  500
312546  2017-09-05  500
312546  2017-10-11  500
312546  2017-11-09  500
312546  2017-12-11  250
312546  2018-01-16  250
312546  2018-02-20  250
312546  2018-03-20  250
312546  2018-04-23  500
312546  2018-04-23  50
312546  2018-05-29  500
312546  2018-07-03  500
312546  2018-07-31  204

任何对我转错位置的见解都将受到赞赏。

2 个答案:

答案 0 :(得分:0)

首先建立该期间所有付款的滚动总和。然后选择总和大于或等于10000的所有对象,并使用row_number()添加最早的日期。

SELECT number,
       datepaid,
       totalpaid
       FROM (SELECT number,
                    datepaid,
                    totalpaid,
                    row_number() OVER (PARTITION BY number
                                       ORDER BY datepaid) rn
                    FROM (SELECT number,
                                 datepaid,
                                 sum(totalpaid) OVER (PARTITION BY number
                                                      ORDER BY datepaid) totalpaid
                                 FROM #accounts                                     
                                 WHERE datepaid >= dateadd(day, -365, convert(date, getdate()))) x
                    WHERE totalpaid >= 10000) y
       WHERE rn = 1;

请确保不要像以前一样PARTITION BY number number, datepaid之前。这实际上使每一行保持原样。 (然后,您还只需要ORDER BY datepaidnumber是多余的(在组中的每个地方都是相等的。但是它不会产生错误的结果。)

答案 1 :(得分:0)

首先,我们根据日期过滤付款并计算每个帐户的付款余额。

第二,我们过滤大于或等于10000的流动余额,并计算每个帐户剩余付款的行数。

最后,我们为每个人支付第一笔款项。

;WITH
[RunningBalance]
AS
(
    SELECT
         [Number]
        ,[DatePaid]
        ,[TotalPaid]
        ,[RunningBalance] = SUM([TotalPaid]) OVER (PARTITION BY [Number] ORDER BY [DatePaid] ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
    FROM #Accounts
    WHERE ([DatePaid] >= DATEADD(DAY, -365, CONVERT(DATE, GETDATE())))
),
[PaymentOverTotal]
AS
(
    SELECT
         [Number]
        ,[DatePaid]
        ,[TotalPaid]
        ,[RunningBalance]
        ,[RN] = ROW_NUMBER() OVER (PARTITION BY [Number] ORDER BY [DatePaid])
    FROM [RunningBalance]
    WHERE [RunningBalance] >= 10000
)
SELECT
     [Number]
    ,[DatePaid]
    ,[TotalPaid]
    ,[RunningBalance]
FROM [PaymentOverTotal]
WHERE ([RN] = 1);