2014-12-04 91 views
0

这里是什么I'm做:显示LastDateOfMonth即使是没有价值

WITH cte AS (
    SELECT * FROM TimeDim 
) 
SELECT t.TimeDimPK, c.ID 
FROM CTE AS t 
LEFT OUTER JOIN TABLE c ON c.TimeDimFK = t.TimeDimPK 
ORDER BY t.TimeDimPK 
WHERE c.ID = 1 

的结果,这是缺少日期如下:

TimeDimPK ID 
20120930 1 
20121231 1 
20130131 1 

什么我正尝试获得

TimeDimPK ID 
20120930 1 
20121031 NULL 
20121130 NULL 
20121231 1 
20130131 1 

回答

1

看起来你的WHERE条款正在摆脱其他日期。试试这个:

WITH cte 
      AS (SELECT TimedimPK 
       FROM  TimeDim 
      ) 
    SELECT t.TimeDimPK , 
      c.ID 
    FROM cte t 
      LEFT OUTER JOIN TABLEname c ON c.TimeDimFK = t.TimeDimPK 
    WHERE c.ID = 1 
      OR c.ID IS NULL 
    ORDER BY t.TimeDimPK 
+0

这不会为我工作:( 我需要查询生成,其中缺少的日期,同时使用一个ID的地方。 – AceAlfred 2014-12-04 16:24:25

+0

您需要提供更多描述性反馈,然后“这不适合我”。当你运行查询时,缺少什么? – 2014-12-04 16:32:08

+0

我需要查询来生成丢失的日期,同时在特定的ID上使用where条件。 – AceAlfred 2014-12-05 09:52:02

0

您可以尝试使用“数字/日期发生器”,这个查询将在所有失踪天填写,然后选择该月的最后一天。我不知道你的所有数据的细节,所以我现在给你两个建议:

1 - 紧凑建议:

DECLARE @minDate DATETIME, @maxDate DATETIME; 

SELECT @minDate = MIN(TimeDimPK), @maxDate = MAX(TimeDimPK) FROM TimeDim; 

WITH DateGenerator AS 
(
    --Create a list with a lot of dates from @minDate 
    SELECT TimeDimPK = CONVERT(DATE, DATEADD(dd, ROW_NUMBER() OVER (ORDER BY OBJECT_ID), @minDate)) FROM sys.objects 
) 
--List all days, including missing days 
SELECT TimeDimPK 
, c.ID 
FROM DateGenerator n 
LEFT JOIN AnotherTable c ON c.TimeDimFK = n.TimeDimPK 
WHERE 
--Stop the number generator at the last day of the last month from the cte table 
n.TimeDimPK <= CONVERT(DATE, DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0, @maxDate)+1,0))) 
--This will get the last day of every month 
AND TimeDimPK = CONVERT(DATE, DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,TimeDimPK)+1,0))) 



2 - 建议你的CTE子句,如果你想用它进行一些调整:

WITH NumberGenerator AS 
(
    --Create a number list 1,2,3,4,5,6,7,8,++ 
    SELECT Number = ROW_NUMBER() OVER (ORDER BY OBJECT_ID) FROM sys.objects 
), cte AS (
    --Your cte query with a date number based on the days between the firts and current days 
    SELECT 
    TimeDimPK = CONVERT(DATETIME, TimeDimPK) 
    --Get the number of days to add from the first day in your table 
    , DateNumber = DATEDIFF(dd, MIN(TimeDimPK) OVER(), TimeDimPK) 
    FROM #TimeDim 
), TableWithMissingDates AS 
(
    --Fill missing days 
    SELECT TimeDimPK = CONVERT(DATE, DATEADD(dd, n.Number - 1, MIN(t.TimeDimPK) OVER())) 
    , c.ID 
    FROM NumberGenerator n 
    LEFT JOIN cte t ON t.DateNumber = n.Number 
    LEFT JOIN #Test2 c ON c.TimeDimFK = t.TimeDimPK 
    --Stop the number generator at the last day of the last month from the cte table 
    WHERE CONVERT(DATE, DATEADD(dd, n.Number - 1, (SELECT MIN(TimeDimPK) FROM cte))) < CONVERT(DATE, DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0, (SELECT MAX(TimeDimPK) FROM cte))+1,0))) 
) 
SELECT * FROM TableWithMissingDates 
WHERE 
--This will get the last day of every month 
TimeDimPK = CONVERT(DATE, DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,TimeDimPK)+1,0))) 



两个查询将返回相同的表:

enter image description here