SQL Lead / Lag,直到达到特定条件为止,并使用符合条件的行中的值更新前一行/后一行

时间:2019-03-14 07:06:16

标签: sql sql-server tsql

假设我的数据集如下:

Customer    Document    Date        Date Cleared
151         Invoice     18.02.2019  null
151         Receipt     14.02.2019  14.02.2019
151         Invoice     18.01.2019  null
151         Invoice     18.12.2018  null
151         Invoice     19.11.2018  null
152         Receipt     7.11.2018   7.11.2018
152         Invoice     18.10.2018  null
152         Invoice     18.09.2018  null
152         Receipt     26.09.2018  26.09.2018
152         Invoice     20.08.2018  null

这只是一个有2个客户的示例。我想知道何时根据最接近的收据付款发票(因为发票是按日期排序的)。

我要完成的工作是用每个客户的先前收据的日期更新发票。

预期输出:

Customer    Document    Date        Date Cleared
151         Invoice     18.02.2019  null
151         Receipt     14.02.2019  14.02.2019
151         Invoice     18.01.2019  14.02.2019
151         Invoice     18.12.2018  14.02.2019
151         Invoice     19.11.2018  14.02.2019
152         Receipt     7.11.2018   7.11.2018
152         Invoice     18.10.2018  7.11.2018
152         Invoice     18.09.2018  7.11.2018
152         Receipt     26.09.2018  26.09.2018
152         Invoice     20.08.2018  26.09.2018

我认为使用简单的滞后/提前功能可以很容易,但是在收据之前可能有1张以上的发票,因此必须滞后直到单据栏为收据。同样,在此示例中,每个客户的第一行可以是发票或收据。如果发票是第一行,则我们假设尚未付款(清除)。

该解决方案甚至可能不涉及滞后或超前功能,这只是我最初的想法。

我将不胜感激。

1 个答案:

答案 0 :(得分:1)

欢迎堆栈溢出! 试试这个:

DECLARE @Table TABLE
(
    Id INT IDENTITY PRIMARY KEY,
    Customer INT,
    Document VARCHAR(100),
    Date DATE,
    DateCleared DATE
)

INSERT INTO @Table
VALUES
(151, 'Invoice', '20190218', NULL),
(151, 'Receipt', '20190214', '20190214'),
(151, 'Invoice', '20190118', NULL),
(151, 'Invoice', '20181218', NULL),
(151, 'Invoice', '20181119', NULL),
(152, 'Receipt', '20181107', '20181107'),
(152, 'Invoice', '20181018', NULL),
(152, 'Invoice', '20180918', NULL),
(152, 'Receipt', '20180926', '20180926'),
(152, 'Invoice', '20180820', NULL)

UPDATE invoice
SET DateCleared = matchingReceipt.DateCleared
FROM @Table AS invoice CROSS APPLY
    (
        SELECT TOP(1) receipt.DateCleared
        FROM @Table AS receipt
        WHERE invoice.Customer = receipt.Customer AND
            invoice.Date < receipt.Date AND
            receipt.Document = 'Receipt'
        ORDER BY DateCleared ASC
    ) AS matchingReceipt
WHERE invoice.Document = 'Invoice'

SELECT * FROM @Table ORDER BY Customer, Date

我在表中添加了一个标识列。您可以使用CROSS APPLY,在给定规则的情况下搜索匹配的收据(相同的客户,在发票后清算并更新)。