TSQL - 缺少月份

时间:2015-08-27 13:44:56

标签: sql-server

我需要在表格中找到丢失的月份 每个ID_No的最早和最晚开始日期。举个例子:

create table #InputTable (ID_No int ,OccurMonth datetime)

insert into #InputTable (ID_No,OccurMonth) 
select 10, '2007-11-01' Union all
select 10, '2007-12-01' Union all
select 10, '2008-01-01' Union all
select 20, '2009-01-01' Union all
select 20, '2009-02-01' Union all
select 20, '2009-04-01' Union all
select 30, '2010-05-01' Union all
select 30, '2010-08-01' Union all
select 30, '2010-09-01' Union all
select 40, '2008-03-01'

对于上表,答案应该是:

ID_No   OccurMonth

-----   ---------- 

20      2009-02-01 

30      2010-06-01 

30      2010-07-01 

此网站上发布的其他解决方案类似,但是:     1)不要包含ID列,     2)不要在数据中使用开始日期/结束日期     3)使用在我的环境中禁止使用的游标。

1 个答案:

答案 0 :(得分:0)

试试这个:

;WITH
    MonthRange AS 
    (
        SELECT      ID_No,
                    MinMonth = MIN(OccurMonth),
                    MaxMonth = MAX(OccurMonth)
        FROM        #InputTable
        GROUP BY    ID_No
    ),
    AllMonths AS
    (
        SELECT      ID_No, 
                    OccurMonth = MinMonth
        FROM        MonthRange
        UNION ALL
        SELECT      a.ID_No,
                    DATEADD(MONTH, 1, a.OccurMonth)
        FROM        AllMonths       a
        INNER JOIN  MonthRange      r   ON a.ID_No = r.ID_No
        WHERE       a.OccurMonth < r.MaxMonth
    )


SELECT      a.*
FROM        AllMonths       a
LEFT JOIN   #InputTable     i   ON a.ID_No = i.ID_No
                                AND a.OccurMonth = i.OccurMonth
WHERE       i.ID_No IS NULL
OPTION      (MAXRECURSION 0)

AllMonths是一个递归CTE,列出了每个ID_no的最小和最大月份之间的所有月份。然后,它只是一个简单的LEFT JOIN来查找中间缺少的月份。