开发者

Understanding TSQL Coalesce function

I am trying to select all 12 months / year. And I thought following TSQL code would do this. However, this does not include all months like I want. What is the cause of this? This is modified code:

DECLARE @END_YEAR VARCHAR(10)
DECLARE @END_MONTH VARCHAR(10)

SET @END_YEAR = '2010'
SET @END_MONTH = '10'

DECLARE @TheMonthLastDate DATETIME
DECLARE @TempDate DATETIME
SET @TempDate = '2010-11-01 00:00:00.000'
SET @TheMonthLastDate = '2010-11-01 00:00:00.000'

;with months
as  
(
select dateadd(month, -1, dateadd(day, datediff(day, 0, @TempDate), 0)) as m
union all
select dateadd(month, -1, m)
from months
where   m > dateadd(month, -12, @TempDate)
)
,yourTable(DateOpened, DateClosed)
as
(select TSK_START_DATE, BTK_CLOSED_DATE
FROM [PROC].ALL_AUDIT
WHERE 
(BTK_CLOSED_DATE < @TheMonthLastDate OR
TSK_START_DATE < @TheMonthLastDate 
)
)
select      yt.DateClosed 'r2', m.m 'r3',
        month(coalesce(yt.DateClosed, m.m)) as 'MonthClosed',
        year(coalesce(yt.DateClosed, m.m)) as 'YearClosed'
from    months m
left join yourTable yt
    on      
    (  datepart(year, yt.DateClosed) = DATEPART(year, m.m)
    and datepart(month, yt.DateClosed) = DATEPART(month, m.m) 
    or    
      datepart(year, yt.DateOpened) = DATEPART(year, m.m)
    and datepart(month, yt.DateOpened) = DATEPART(month, m.m) 
    )
AND year(coalesce(yt.DateClosed, m.m)) = 2010
order by yt.DateClosed

So above query does not return all months. But if I change above WHERE lines to:

FROM [PROC].ALL_AUDIT
    WHERE
BTK_CLOSED_DATE < @TheMonthLastDate

then this query does return all 12 months. How can this be?

Output that I want and that I see when WHERE is BTK_CLOSED_DATE < @TheMonthLastDate:

r2  r3  MonthClosed YearClosed
NULL 开发者_如何学C   2010-06-01 00:00:00.000 6   2010
NULL    2009-11-01 00:00:00.000 11  2009
2010-01-06 20:02:19.127 2010-01-01 00:00:00.000 1   2010
2010-01-27 23:13:45.570 2010-01-01 00:00:00.000 1   2010
2010-02-15 14:49:14.427 2010-02-01 00:00:00.000 2   2010
2010-02-15 14:49:14.427 2009-12-01 00:00:00.000 2   2010

But if I instead use WHERE: (BTK_CLOSED_DATE < @TheMonthLastDate OR TSK_START_DATE < @TheMonthLastDate )

then I see:

r2  r3  MonthClosed YearClosed
NULL    2010-10-01 00:00:00.000 10  2010
NULL    2010-09-01 00:00:00.000 9   2010
NULL    2010-09-01 00:00:00.000 9   2010
NULL    2010-08-01 00:00:00.000 8   2010
NULL    2010-08-01 00:00:00.000 8   2010
...

So notice that in first result I see NULL for June 2010, which is what I want. I think the problem has something to do with the fact that my data contains 2009-2011 data, but I only compare months and not years. How would I add in this additional logic?


The only place where you are reducing the data is with the WHERE clause you have already identified. Therefore, the reason you are not getting all the months you expect is down to the column TSK_START_DATE not being less than @TheMonthLastDate for all months.

To prove this hypothesis, run the following section of your query (I have commented out part of the where clause and removed everything under 'yourTable' cte). The results should show you what is being returned in the TSK_Start_Date column for your missing months and help you identify why the rows are missing when applying the < @TheMonthLastDate clause.

DECLARE @END_YEAR VARCHAR(10)
DECLARE @END_MONTH VARCHAR(10)

SET @END_YEAR = '2010'
SET @END_MONTH = '10'

DECLARE @TheMonthLastDate DATETIME
DECLARE @TempDate DATETIME
SET @TempDate = '2010-11-01 00:00:00.000'
SET @TheMonthLastDate = '2010-11-01 00:00:00.000'

;with months
as  
(
select dateadd(month, -1, dateadd(day, datediff(day, 0, @TempDate), 0)) as m
union all
select dateadd(month, -1, m)
from months
where   m > dateadd(month, -12, @TempDate)
)

,yourTable(DateOpened, DateClosed)
as
(select TSK_START_DATE, BTK_CLOSED_DATE
FROM [PROC].ALL_AUDIT
WHERE 
(BTK_CLOSED_DATE < @TheMonthLastDate OR
--TSK_START_DATE < @TheMonthLastDate 
)
)
select * , @TheMonthLastDate TheMonthLastDate from yourTable
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜