Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/86.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 使用更改余额的值进行减法,以查找单个日期值_Sql_Sql Server - Fatal编程技术网

Sql 使用更改余额的值进行减法,以查找单个日期值

Sql 使用更改余额的值进行减法,以查找单个日期值,sql,sql-server,Sql,Sql Server,作为我正在编写的一份更大报告的一部分,我需要找到客户根据其账户余额付款将导致超额付款的具体日期。我已经尝试了几种方法,但都没有成功,但我目前正在尝试一种方法: WITH [BalanceMath] AS ( SELECT number AS [Account], currentbalance AS [balance], paymentamount FROM #PaymentInfo GROUP BY number, currentbalance, paymentamount UNION ALL

作为我正在编写的一份更大报告的一部分,我需要找到客户根据其账户余额付款将导致超额付款的具体日期。我已经尝试了几种方法,但都没有成功,但我目前正在尝试一种方法:

WITH [BalanceMath] AS (
SELECT number AS [Account], currentbalance AS [balance], paymentamount
FROM #PaymentInfo
GROUP BY number, currentbalance, paymentamount
UNION ALL
SELECT Account, balance - paymentamount, paymentamount
FROM [BalanceMath]
WHERE [balance] >= 0

)
SELECT * FROM [BalanceMath]
ORDER BY 1 asc, 2 desc
OPTION (MAXRECURSION 32767)
GO
有关输入的重要注意事项:

有多个帐户 付款金额可能会因不同的付款而有所不同,最常见的情况是最终付款金额与其他付款金额不同,因此我没有一个一致的金额可供使用。我需要单独考虑每笔付款。 以下是我上述查询的一些输出:

    Account balance   paymentamount
    123456  547.4906    115
    123456  547.4906    51.77
    123456  495.7206    51.77
    123456  443.9506    51.77
    123456  432.4906    115
    123456  392.1806    51.77
    123456  340.4106    51.77
    123456  317.4906    115
    123456  288.6406    51.77
    123456  236.8706    51.77
    123456  202.4906    115
    123456  185.1006    51.77
    123456  133.3306    51.77
    123456  87.4906     115
    123456  81.5606     51.77
    123456  29.7906     51.77
    123456  -21.9794    51.77
    123456  -27.5094    115
此帐户上只剩下9笔付款,但由于付款金额不同,返回了18行。当我试图包含我真正需要的信息,即付款日期时,问题变得更糟。然后,行计数跳到48。以下是我从中提取数据的临时表中的数据外观:

    ID      Account paymentdate paymentamount   currentbalance
    1080219 123456  3/25/2018   115             547.4906
    1080220 123456  4/25/2018   115             547.4906
    1080221 123456  5/25/2018   115             547.4906
    1080222 123456  6/25/2018   115             547.4906
    1080223 123456  7/25/2018   115             547.4906
    1080224 123456  8/25/2018   115             547.4906
    1080225 123456  9/25/2018   115             547.4906
    1080226 123456  10/25/2018  115             547.4906
    1080227 123456  11/25/2018  51.77           547.4906
有关临时表数据的注释:

这些数据驻留在多个表中,因此我将其收集到一个表中,但如果这有助于查询的话,可以很容易地将其分为两个表。 currentbalance在每一行上都是相同的,因为数据是从多个表中提取的,并且我们没有保持currentbalance随付款递减的运行预测,因此我尝试在这里进行查询。 我最终需要付款的paymentdate,该付款将发送客户的余额为负数,但如果需要,可以使用ID,因为每个ID都与付款日期唯一关联。 此临时表中的帐户肯定会超额付款。我已经从所有其他帐户中筛选出了它们。
递归查询可能不是这里的解决方案,除非有人知道如何让它单独读取每笔付款,所以我愿意接受任何关于我可以尝试实现预期结果的建议。谢谢。

假设您使用的是较新版本的SQL Server,您可以尝试以下操作:

WITH Balances1 AS
(
    SELECT *,
        CurrentBalance - SUM(PaymentAmmount) OVER (PARTITION BY Account ORDER BY PaymentDate, ID) AS Balance
    FROM #tt
)
, Balances2 AS
(
    SELECT *, ISNULL(LAG(Balance) OVER (PARTITION BY Account ORDER BY PaymentDate, ID), 0) AS Prev
    FROM Balances1
)
SELECT *
FROM Balances2
WHERE Balance < 0 AND Prev >= 0
这里的想法是创造一个连续的平衡,这样我们就知道什么值是负的。这是第一个CTE余额1。 第二个1平衡2只是将上一个平衡放在同一行中,因此我们可以检测到平衡何时变为负数


然后外部查询进行过滤。试一试,让我们知道它是否正常工作和执行。

只是为了检查我是否理解,在您的临时表示例中,您希望返回第1080223行和日期为2018年7月25日?是@kirchner,这完全正确。我应该包括在内。谢谢@kirchner这看起来很有希望。我的结果集与我预期的不同帐户数略有出入,因此我需要花一些时间检查被排除的帐户,看看它们是否应该被包括在内。在此之后,我将知道这是否需要更多的调整,或者查询中的其他地方是否需要调整。我会在复习完后发布我的结果。好的@kirchner我知道问题是什么,但不一定是解决办法。您的查询工作正常,除非下一次付款是将帐户发送到超额付款的付款。我不知道是否可以修改您的查询以正确解释此问题,我将不得不稍微处理一下。否则,由于我已经知道哪些帐户会多付,所以我可能需要解决的一个问题是,为任何不在查询结果集中的帐户选择MINpaymentdate。你帮了大忙,谢谢你,我真的很感激。你是说临时表中的第一条记录是你需要的吗?我建议的查询使用LAG函数查看以前的记录,因此我从未考虑过这种可能性。你能证实我在这篇评论中的理解是正确的吗?我认为这可能是一个简单的改变。如果我理解正确,看起来所需要的改变是微不足道的。我更新了答案。在滞后周围添加了一个ISNULL。这修复了它。非常感谢你!我肯定需要再次阅读滞后、超前和窗口。很容易忘记查询中不经常使用的东西。