SQL Lead / Lag до определенного условия и обновляет предыдущие / следующие строки значением из строки, которая попадает в условие - PullRequest
1 голос
/ 14 марта 2019

Предположим, у меня есть набор данных, как показано ниже:

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 Ответ

1 голос
/ 14 марта 2019

Добро пожаловать в переполнение стека!Попробуйте это:

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 для поиска соответствующей квитанции с учетом ваших правил (тот же клиент, очищенный после выставления счета и более поздний).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...