了解 TSQL 合并函数

发布于 2024-11-26 19:29:43 字数 2415 浏览 1 评论 0原文

我正在尝试选择所有 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 is BTK_CLOSED_DATE < 时我看到的输出@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 < @TheMonthLastDate 或 TSK_START_DATE < @月末日期 )

然后我看到:

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年的数据有关,但我只比较月份而不是年份。我如何添加这个额外的逻辑?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

做个少女永远怀春 2024-12-03 19:29:43

减少数据的唯一地方是您已经确定的 WHERE 子句。因此,您没有获得预期的所有月份的原因是所有月份的 TSK_START_DATE 列不小于 @TheMonthLastDate。

为了证明这个假设,请运行查询的以下部分(我已经注释掉了部分 where 子句并删除了“yourTable”cte 下的所有内容)。结果应显示 TSK_Start_Date 列中针对缺失月份返回的内容,并帮助您确定应用 << 时缺失行的原因。 @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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文