2014-10-20 70 views
4

我有如下表:TSQL - 我如何找到日期之間缺失的月份?

UserID | DeptNumber | BeginDate   | EndDate    | 
123456 | 1000010001 | 2013-11-15 00:00:00 | 2014-04-24 00:00:00 | 
789012 | 1000010002 | 2014-04-25 00:00:00 | 2014-07-01 00:00:00 | 
345678 | 1000010003 | 2014-07-02 00:00:00 | NULL    | 

我怎麼能填充缺失的幾個月,所以我有這樣的事情:

UserID | DeptNumber | Month 
123456 | 1000010001 | 11 
123456 | 1000010001 | 12 
123456 | 1000010001 | 1 
123456 | 1000010001 | 2 
123456 | 1000010001 | 3 
789012 | 1000010002 | 4 
789012 | 1000010002 | 5 
789012 | 1000010002 | 6 
345678 | 1000010003 | 7 
345678 | 1000010003 | 8 
345678 | 1000010003 | 9 
345678 | 1000010003 | 10 
+1

Endate爲NULL,那麼您的值是如何得到第10個月的值? – 2014-10-20 21:46:41

回答

1

如果結束日期不是null和日期是像「2014-10 -30' ,那麼這可能會幫助你

CREATE TABLE #tblName 
    (
    UserID  INT, 
    startdate DATETIME, 
    endate  DATETIME, 
    DeptNumber BIGINT 
) 

INSERT INTO #tblName 
VALUES  (123456,'2013-11-15 00:00:00','2014-04-24 00:00:00',1000010001), 
      (789012,'2014-04-25 00:00:00','2014-07-01 00:00:00',1000010002), 
      (345678,'2014-07-02 00:00:00','2014-10-30 00:00:00',1000010003) 

DECLARE @mindate DATETIME, 
     @maxdate DATETIME 

SELECT @mindate = Min(startdate), 
     @maxdate = Max(endate) 
FROM #tblName; 

WITH cte 
    AS (SELECT @mindate startdate 
     UNION ALL 
     SELECT Dateadd(mm, 1, startdate) startdate 
     FROM cte 
     WHERE startdate <= @maxdate) 
SELECT userid, 
     DeptNumber, 
     Datepart(mm, a.startdate) [Month] 
FROM cte a 
     JOIN #tblName b 
     ON a.startdate BETWEEN b.startdate AND b.endate 

輸出

userid DeptNumber Month 

123456 1000010001 11 
123456 1000010001 12 
123456 1000010001 1 
123456 1000010001 2 
123456 1000010001 3 
123456 1000010001 4 
789012 1000010002 5 
789012 1000010002 6 
345678 1000010003 7 
345678 1000010003 8 
345678 1000010003 9 
345678 1000010003 10 
1

這應該適用於您提供的示例的NULL結束日期。

DECLARE @Data TABLE (UserID INT, DeptNumber BIGINT, BeginDate DATETIME, EndDate DATETIME) 
INSERT @Data VALUES 
    (123456, 1000010001, '2013-11-15', '2014-04-24'), 
    (789012, 1000010002, '2014-04-25', '2014-07-01'), 
    (345678, 1000010003, '2014-07-02', NULL) 
DECLARE 
    @MinDate DATETIME = (
     SELECT 
      CONVERT(DATE, CONVERT(VARCHAR(10), YEAR(MIN(BeginDate))) 
       + '-' + CONVERT(VARCHAR(10), MONTH(MIN(BeginDate))) 
       + '-1') AS [Day] 
     FROM @Data 
    ), @MaxDate DATETIME = (SELECT DATEADD(YY, 2, MAX(EndDate)) FROM @Data) 
;WITH Months AS (
    SELECT @MinDate AS [Day] 
    UNION ALL 
    SELECT 
     DATEADD(MM, 1, [Day]) 
    FROM Months 
    WHERE DATEADD(MM, 1, [Day]) <= @MaxDate 
) 
    SELECT DISTINCT 
     Users.UserID, 
     Users.DeptNumber, 
     MONTH([Day]) AS [Month] 
    FROM Months 
     CROSS JOIN @Data Users 
     LEFT OUTER JOIN @Data Data 
      ON (Users.UserID = Data.UserID AND Users.DeptNumber = Data.DeptNumber) 
       AND (Data.BeginDate IS NULL OR Data.BeginDate >= [Day]) 
       AND (Data.EndDate IS NULL OR Data.EndDate <= [Day]) 
    WHERE Data.UserID IS NULL 
+0

這應該適用於空結束日期 – 2014-10-20 22:00:18

+0

您的查詢是否符合預期的輸出?我希望這不會返回deptno 1000010003 – 2014-10-20 22:07:19

+0

現在確實如此。我原本以爲你只是想通過最大日期,但現在它正常工作,並排除了deptno – 2014-10-20 22:36:11

相關問題