在SQL中使用贷方付款日期和合计获取借方的付款日期-慢速查询

在SQL中使用贷方付款日期和合计获取借方的付款日期-慢速查询,sql,tsql,sql-server-2012,Sql,Tsql,Sql Server 2012,Edit2:CTE是查询速度慢的原因。问题解决了 编辑:我将创建另一列付款日期,而不是更新。下面的代码工作得很好,但是速度非常慢。有没有其他方法可以更快地做到这一点 WITH sum_data AS (SELECT CustomerID , ISSUEDATE , DEBIT , CREDIT , SUM(DEBIT) over(PARTITIO

Edit2:CTE是查询速度慢的原因。问题解决了

编辑:我将创建另一列付款日期,而不是更新。下面的代码工作得很好,但是速度非常慢。有没有其他方法可以更快地做到这一点

WITH sum_data AS (SELECT CustomerID
                   , ISSUEDATE
                   , DEBIT
                   , CREDIT
                   , SUM(DEBIT) over(PARTITION BY CustomerID 
                                     ORDER BY ISSUEDATE
                                     ROWS UNBOUNDED PRECEDING) SUM_DEBIT
                   , SUM(CREDIT) over(PARTITION BY CustomerID
                                      ORDER BY ISSUEDATE
                                      ROWS UNBOUNDED PRECEDING) SUM_CREDIT
               FROM Test_Table)
SELECT d.CustomerID
 , d.ISSUEDATE
 , d.DEBIT
 , d.CREDIT
 , (SELECT MIN(ISSUEDATE) 
               FROM sum_data d2
               WHERE d2.SUM_CREDIT >= d.SUM_DEBIT
                 AND d2.CustomerID  = d.CustomerID) PAYMENTDATE
FROM sum_data d
WHERE DEBIT != 0 
预编辑:我有一个数据集,显示不同客户的交易信息。信用额度的发放日期和支付日期相同,因为它们是同时发放和支付的。但是,对于借方行,付款日期将为贷方清算该借方时。因此,从底部开始,在进入贷方之前,我们有4个借方。1398.83贷方结算1336.13借方的金额,因此我想用2018年9月20日的付款日期更新最后一行。上面的2672条信用证涵盖了1398.83的倒数第二行,因此该行的付款日期应为2018年9月22日。(1398.83-1336.13)+(2672-1398.83)的剩余余额不包括剩余的借方,因此我们将继续检查新的贷方行是否包括借方金额,并将开始清算借方(如更新付款日期)从最后一个条目开始,当借方清算时,我们将使用清算贷方行的付款日期更新付款日期,如上述示例所示。这将针对所有不同的客户ID(按分区)完成

上述查询在此数据集上的输出:

CustomerID  ISSUEDATE   DEBIT    CREDIT PAYMENTDATE
M00008      2018-08-02  1336.13  0.00   2018-09-20
M00008      2018-08-03  1398.83  0.00   2018-09-22
M00008      2018-09-03  1398.83  0.00   2018-10-19
M00008      2018-09-03  1336.13  0.00   2018-10-20
M00008      2018-10-02  1541.03  0.00   2018-11-19
M00008      2018-10-03  1489.94  0.00   2018-11-19
M00008      2018-11-02  1367.92  0.00   2018-11-19
M00008      2018-11-05  1461.56  0.00   2018-11-19
M00008      2018-12-03  1513.03  0.00   2019-01-22
M00008      2018-12-03  1336.13  0.00   2019-01-28
M00008      2019-01-04  1398.83  0.00   2019-02-21
M00008      2019-01-04  1336.13  0.00   2019-02-21
M00008      2019-02-04  1403.40  0.00   2019-03-18
M00008      2019-02-04  1336.13  0.00   2019-03-18
M00008      2019-03-04  1406.13  0.00   NULL
M00008      2019-03-04  1336.13  0.00   NULL
M00008      2019-04-02  1345.53  0.00   NULL

在select语句中使用select将始终对性能产生影响。对于您的查询,使用交叉应用应该可以更快地生成结果

WITH sum_data AS (SELECT CustomerID
               , ISSUEDATE
               , DEBIT
               , CREDIT
               , SUM(DEBIT) over(PARTITION BY CustomerID 
                                 ORDER BY ISSUEDATE
                                 ROWS UNBOUNDED PRECEDING) SUM_DEBIT
               , SUM(CREDIT) over(PARTITION BY CustomerID
                                  ORDER BY ISSUEDATE
                                  ROWS UNBOUNDED PRECEDING) SUM_CREDIT
           FROM Test_Table)
 SELECT d.CustomerID
      , d.ISSUEDATE
      , d.DEBIT
      , d.CREDIT
      , PaymentDate
   FROM sum_data d
   CROSS APPLY (SELECT MIN(ISSUEDATE) AS PaymentDate
           FROM sum_data d2
           WHERE d2.SUM_CREDIT >= d.SUM_DEBIT
             AND d2.CustomerID  = d.CustomerID) t
   WHERE DEBIT != 0 

这是可能的,但我认为这是一个人们一年能挣20万美元以上的问题。您是否有自己编写的某种查询来解决此问题,需要帮助?我想这可能需要一位专业人士花一天的时间来编写,并确保它是防弹的,因此期望有人为您编写整个查询以获得+25的声誉是有点不合理的。我添加了我使用的代码,并稍微更改了措辞。我没有更新,而是创建了另一个名为Payment date的列,上面添加的代码非常有效。然而,这需要很长时间。我想知道是否有其他方法可以更快地完成此操作。请注意,
交叉应用
的工作方式与
内部连接
类似,在
应用
中没有匹配的记录,因此不会返回任何内容。如果需要
左连接
类型行为,可以使用
外部应用
WITH sum_data AS (SELECT CustomerID
               , ISSUEDATE
               , DEBIT
               , CREDIT
               , SUM(DEBIT) over(PARTITION BY CustomerID 
                                 ORDER BY ISSUEDATE
                                 ROWS UNBOUNDED PRECEDING) SUM_DEBIT
               , SUM(CREDIT) over(PARTITION BY CustomerID
                                  ORDER BY ISSUEDATE
                                  ROWS UNBOUNDED PRECEDING) SUM_CREDIT
           FROM Test_Table)
 SELECT d.CustomerID
      , d.ISSUEDATE
      , d.DEBIT
      , d.CREDIT
      , PaymentDate
   FROM sum_data d
   CROSS APPLY (SELECT MIN(ISSUEDATE) AS PaymentDate
           FROM sum_data d2
           WHERE d2.SUM_CREDIT >= d.SUM_DEBIT
             AND d2.CustomerID  = d.CustomerID) t
   WHERE DEBIT != 0