根据简单条件显示下一个日期(LEAD)

时间:2019-04-19 15:29:11

标签: sql-server-2012

我有一张表,该表具有关于居住在房屋中的客户合同的唯一索引,我想知道下一个人要居住一所房屋要花费多少天。

我已经很远了,但是很遗憾,我的数据集具有TYPE = 0的合同,这些合同是系统自动生成的,应该忽略, 如果我不忽略TYPE = 0的这些“空合同”,那么数据表明实际上所有房屋都在1天内有人居住。

现在,我目前得到以下结果:

SELECT
CONTRACTID
,RENTALOBJECTID
,TYPE
,VALIDFROM
,VALIDTO
,LEAD(CONTRACTID) OVER (PARTITION BY RENTALOBJECTID ORDER BY VALIDFROM) AS 'NextContractId'
,LEAD(VALIDFROM)  OVER (PARTITION BY RENTALOBJECTID ORDER BY VALIDFROM) AS 'NextValidFrom'
,LEAD(VALIDTO)    OVER (PARTITION BY RENTALOBJECTID ORDER BY VALIDFROM) AS 'NextValidTo'
FROMPMCCONTRACT

使用以下代码:

CONTRACTID  RENTALOBJECTID  TYPE    VALIDFROM   VALIDTO     NextContractId  NextValidFrom   NextValidTo
HC001       1               0       1/1/2015    1/1/2017    HC002           1/2/2017        8/1/2017
HC002       1               0       1/2/2017    8/1/2017    HC003           8/2/2017        NULL
HC003       1               3       8/2/2017    NULL        NULL            NULL            NULL

但是我希望结果看起来像下面的样子,它忽略了TYPE = 0的Contracts。

CONTRACTID  RENTALOBJECTID  TYPE    VALIDFROM   VALIDTO     NextContractId  NextValidFrom   NextValidTo
HC001       1               3       1/1/2015    1/1/2017    HC003           8/2/2017        NULL
HC002       1               0       1/2/2017    8/1/2017    NULL            NULL            NULL
HC003       1               3       8/2/2017    NULL        NULL            NULL            NULL

现在您可以看到,在CONTRACT = HC001已经超过一个月之后,RENTALOBJECTID = 1再次被居住的时间。

有人知道它在SQL-server-2012中如何工作吗?

亲切的问候,

伊戈尔

1 个答案:

答案 0 :(得分:1)

您的示例数据有些不一致,因此您省略了对预期结果的某些解释,但这基本上可以满足您的要求。

窗口框架设置为VALIDFROM降序排列,因此ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING包括具有更高VALIDFROM的所有行。只有拥有TYPE <> 0的人会得到不为空的ConcatResult,而MIN会选择该窗口帧中VALIDFROM最低的那个(即,当前行的第二大)。然后,将三个串联的列值从该结果中拉出。

WITH PMC
     AS (SELECT CONTRACTID,
                RENTALOBJECTID,
                TYPE,
                VALIDFROM,
                VALIDTO,
                ConcatResult = MIN(CASE
                                     WHEN TYPE <> 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