Показать следующую дату (время выполнения) с несколькими условиями - PullRequest
0 голосов
/ 05 июня 2019

Для начала я представлю свою первую проблему, которую я решил, а затем объясню дополнительные условия, добавленные в уравнение.

У меня есть таблица с уникальным индексом контрактов клиентов, которые живут в домах, и я хочу знать, сколько дней требуется, чтобы дом заселился следующим человеком. Мы также создаем «пустые» контракты в то время, когда дом пуст, поэтому мы можем рассчитать, что $$ мы пропустили, выбрав «пустые» контракты.

Это работает так: AGREEMENTTYPE = 0 означает жилой AGREEMENTTYPE = 3 означает пусто

Теперь я хочу узнать, сколько дней требуется, чтобы дом (RENTALOBJECTID) снова заселился после того, как кто-то вышел. Так, например:

RENTALOBJECTID 1, CONTRACTID HC001, AGREEMENTTYPE 0, ended 3/1/2019
RENTALOBJECTID 1, CONTRACTID HC002, AGREEMENTTYPE 3, starts 3/1/2019, ends 6/1/2019 (the empty contract in between).
RENTALOBJECTID 1, CONTRACTID HC003, AGREEMENTTYPE 0, starts 6/1/2019

Общее время между HC001 и HC003 составляет 3 месяца.

У меня есть запрос, который уже отлично вычисляет это, но теперь он начинает становиться интересным. Сначала я покажу вам, что у меня есть:

WITH PMC
     AS (SELECT CONTRACTID,
                RENTALOBJECTID,
                AGREEMENTTYPE,
                VALIDFROM,
                VALIDTO,
                ConcatResult = MIN(CASE
                                 WHEN AGREEMENTTYPE <> 0
                                   THEN FORMAT(VALIDFROM, 'yyyy-MM-dd')
                                        + FORMAT(ISNULL(VALIDTO, '1900-01-01'), 'yyyy-MM-dd')
                                        + CONTRACTID
                               END)
                             OVER (
                               PARTITION BY RENTALOBJECTID
                               ORDER BY VALIDFROM DESC 
                               ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING)
     FROM   PMCCONTRACT)
SELECT *,
   NextContractId = SUBSTRING(ConcatResult, 21, 10),
   NextValidFrom = CAST(SUBSTRING(ConcatResult, 1, 10) AS DATE),
   NextValidTo = CAST(NULLIF(SUBSTRING(ConcatResult, 11, 10), '1900-01-01') AS DATE)
FROM   PMC
ORDER  BY RENTALOBJECTID,
      VALIDFROM

Что приводит к следующим данным:

CONTRACTID  RENTALOBJECTID  AGREEMENTTYPE   STATECODE   VALIDFROM   VALIDTO     NextContractID  NextValidFrom   NextValidTo 
HC001       1               3               NULL        1/1/2015    3/1/2019    HC004           6/1/2019        NULL        
HC002       1               0               2           3/1/2019    4/1/2019    NULL            NULL            NULL        
HC003       1               0               1           4/1/2019    6/1/2019    NULL            NULL            NULL        
HC004       1               3               NULL        6/1/2019    NULL        NULL            NULL            NULL        

Тем не менее, в некоторых случаях между AND имеется несколько контрактов RE AGREEMENTTYPE = 3 ’, которые относятся к определенному типу, который вы не хотите включать во время выполнения заказа. Мы называем это «STATECODE». Контракты с AGREEMENTTYPE = 3, с STATECODE = 2, которые мы не хотим включать в расчет времени выполнения заказа в днях.

Следующий пример показывает, что я имею в виду:

RENTALOBJECTID 1, CONTRACTID HC001, AGREEMENTTYPE 0, STATECODE NULL, ended 3/1/2019
RENTALOBJECTID 1, CONTRACTID HC002, AGREEMENTTYPE 3, STATECODE 2, starts 3/1/2019, ends 4/1/2019 (the empty contract in between)
RENTALOBJECTID 1, CONTRACTID HC003, AGREEMENTTYPE 3, STATECODE 1, starts 4/1/2019, ends 6/1/2019
RENTALOBJECTID 1, CONTRACTID HC004, AGREEMENTTYPE 0, STATECODE NULL, starts 6/1/2019

Время между контрактом HC001 и HC004 составляет 3 месяца, затем -1 месяц контракта HC002, который мы должны опустить = в общей сложности 2 месяца.

Возможно, у вас есть лучшее предложение, но сейчас я хочу, чтобы данные выглядели следующим образом, поскольку тогда я могу легко рассчитать время выполнения заказа в днях между контрактами для определенного RENTALOBJECTID.

CONTRACTID  RENTALOBJECTID  AGREEMENTTYPE   STATECODE   VALIDFROM   VALIDTO     NextContractID  NextValidFrom   NextValidTo NextStatecode2Contract  NextStatecode2ValidFrom NextStatecode2ValidTo
HC001       1               3               NULL        1/1/2015    3/1/2019    HC004           6/1/2019        NULL        HC002                   3/1/2019                4/1/2019
HC002       1               0               2           3/1/2019    4/1/2019    NULL            NULL            NULL        NULL                    NULL                    NULL
HC003       1               0               1           4/1/2019    6/1/2019    NULL            NULL            NULL        NULL                    NULL                    NULL
HC004       1               3               NULL        6/1/2019    NULL        NULL            NULL            NULL        NULL                    NULL                    NULL

Итак, в основном я хочу рассчитать время между КОНТРАКТАМИ с AGREEMENTTYPE 0, минус период КОНТРАКТОВ с AGREEMENTTYPE 3 и STATECODE 2. Но так как это используется в качестве измерения для моей модели данных, это причина, почему я хочу включите эти последние три как вычисленные столбцы. Столбец должен быть рассчитан где-то по линиям:

NextStatecode2Contract:

IF CONTRACT has AGREEMENTTYPE 3 and IF one of the next contracts has a CONTRACT with AGREEMENTTYPE 0 
AND STATECODE 2 BEFORE the Next Contract with AGREEMENTTYPE 3, 
THEN SELECT THE NEXT CONTRACT OF AGREEMENTTYPE 0 AND STATECODE 2.

NextStatecode2ValidFrom:

IF CONTRACT has AGREEMENTTYPE 3 and IF one of the next contracts has a CONTRACT with AGREEMENTTYPE 0 
AND STATECODE 2 BEFORE the Next Contract with AGREEMENTTYPE 3, 
THEN SELECT VALIDFROM OF THE NEXT CONTRACT OF AGREEMENTTYPE 0 AND STATECODE 2.

NextStatecode2ValidTo

IF CONTRACT has AGREEMENTTYPE 3 and IF one of the next contracts has a CONTRACT with AGREEMENTTYPE 0 
AND STATECODE 2 BEFORE the Next Contract with AGREEMENTTYPE 3, 
THEN SELECT VALIDTO OF THE NEXT CONTRACT OF AGREEMENTTYPE 0 AND STATECODE 2.
...