如何在同一查询中找到缺口日期和最短日期?

时间:2017-12-26 21:12:55

标签: tsql date

我有一个表 customer_history ,其中记录了 customer_id modification_date 。 如果未修改 customer_id ,则表中没有条目 我可以找到 customer_id 未被修改的时间( = last_date_with_no_modification )。我寻找日期缺失的时候(=差距和群岛问题)。

但是在相同的查询中,如果没有日期丢失,则值 last_date_with_no_modification 应该 对于 customer_id ,请DATEADD(DAY,-1,min(modification_date))

我不知道如何在我的SQL查询中添加最后一个条件?

我使用以下表格:

“Customer_history”表

customer_id modification_date
1    2017-12-20
1    2017-12-19
1    2017-12-17
2    2017-12-20
2    2017-12-18
2    2017-12-17
2    2017-12-15
3    2017-12-20
3    2017-12-19

“#tmp_calendar”表格:

date
2017-12-15
2017-12-16
2017-12-17
2017-12-18
2017-12-19
2017-12-20

用于查询差距日期的查询:

WITH CTE_GAP AS 
(SELECT ch.customer_id,
    LAG(ch.modification_date) OVER(PARTITION BY ch.customer_id ORDER BY ch.modification_date) as GapStart,
    ch.modification_date as GapEnd,
    (DATEDIFF(DAY,LAG(ch.modification_date) OVER(PARTITION BY ch.customer_id ORDER BY ch.modification_date), ch.modification_date)-1) GapDays
FROM customer_history ch  ) 
SELECT  cg.customer_id,
    DATEADD(DAY,1,MAX(cg.GapStart)) as last_date_with_no_modification   
FROM CTE_GAP cg
CROSS JOIN #tmp_calendar c
WHERE cg.GapDays >0
AND c.date BETWEEN DATEADD(DAY,1,cg.GapStart) AND DATEADD(DAY,-1,cg.GapEnd)
GROUP BY cg.customer_id

结果:

customer_id last_date_with_no_modification
1    2017-12-18
2    2017-12-19
3    2017-12-19 (Row missing)

如何获取 customer_id 3?

1 个答案:

答案 0 :(得分:0)

这应该有用:

WITH CTE_GAP
AS 
(
    SELECT
        ch.customer_id,
        LAG(ch.modification_date) OVER(PARTITION BY ch.customer_id ORDER BY ch.modification_date) as GapStart,
        ch.modification_date as GapEnd,
        (DATEDIFF(DAY,LAG(ch.modification_date) OVER(PARTITION BY ch.customer_id ORDER BY ch.modification_date), ch.modification_date)-1) GapDays
    FROM @customer_history ch
)

SELECT DISTINCT
    C.customer_id
    , ISNULL(LD.last_date_with_no_modification, LD_NO_GAP.last_date_with_no_modification) last_date_with_no_modification
FROM
    customer_history C
    LEFT JOIN
        (
            SELECT
                cg.customer_id,
                DATEADD(DAY, 1, MAX(cg.GapStart)) last_date_with_no_modification
            FROM
                CTE_GAP cg
                CROSS JOIN #tmp_calendar c
            WHERE
                cg.GapDays >0
                AND c.date BETWEEN DATEADD(DAY, 1, cg.GapStart) AND DATEADD(DAY, -1, cg.GapEnd)
            GROUP BY cg.customer_id
        ) LD
    ON C.customer_id = LD.customer_id
    LEFT JOIN
        (
            SELECT
                customer_id
                , DATEADD(DAY, -1, MIN(modification_date)) last_date_with_no_modification
            FROM customer_history
            GROUP BY customer_id
        ) LD_NO_GAP
    ON C.customer_id = LD_NO_GAP.customer_id