显示具有多个条件的下一个日期(提前期)

时间:2019-06-05 11:46:28

标签: sql-server sql-server-2012

首先,我介绍了我解决的第一个问题,然后解释了添加到方程式中的其他条件。

我有一个表,该表具有关于居住在房屋中的客户合同的唯一索引,我想知道下一个人要居住一所房屋需要多少天。我们还会在房屋空置时创建“空”合同,因此我们可以通过选择“空”合同来计算错过的美元。

它是这样的: 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之间存在多个“ 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个月,那么HC002合同的-1个月我们应该省略= 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的CONTRACTS之间的时间,减去AGREEMENTTYPE 3和STATECODE 2的CONTRACTS的时间。但是由于这被用作我的数据模型的维,所以这就是我想要将这最后三列作为计算列。该列的计算应遵循以下方式:

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.

0 个答案:

没有答案