了解TSQL Coalesce函数

时间:2011-07-28 13:59:04

标签: tsql coalesce

我试图选择所有12个月/年。我认为遵循TSQL代码会这样做。但是,这并不包括我想要的所有月份。这是什么原因?这是修改后的代码:

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

因此上述查询不会返回所有月份。但是,如果我将WHERE行更改为:

FROM [PROC].ALL_AUDIT
    WHERE
BTK_CLOSED_DATE < @TheMonthLastDate

然后此查询确实返回所有12个月。怎么会这样?

我想要的输出,当WHERE是BTK_CLOSED_DATE时我看到的输出&lt; @TheMonthLastDate:

r2  r3  MonthClosed YearClosed
NULL    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

但如果我改为使用WHERE: (BTK_CLOSED_DATE&lt; @TheMonthLastDate OR     TSK_START_DATE&lt; @TheMonthLastDate     )

然后我看到了:

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
...

请注意,在第一个结果中,我看到2010年6月的NULL,这就是我想要的。 我认为这个问题与我的数据包含2009-2011数据这一事实有关,但我只比较了几个月而不是几年。我将如何添加这个额外的逻辑?

1 个答案:

答案 0 :(得分:2)

您减少数据的唯一地方是您已经识别的WHERE子句。因此,您没有得到所期望的所有月份的原因是所有月份的TSK_START_DATE列都不低于@TheMonthLastDate。

为了证明这个假设,请运行查询的以下部分(我已经注释掉了where子句的一部分并删除了'yourTable'cte下的所有内容)。结果应该显示您在缺失月份的TSK_Start_Date列中返回的内容,并帮助您确定在应用&lt;时缺少行的原因。 @TheMonthLastDate子句。

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