Tsql 在SQL Server 2008R2上打印当前年份的所有日期
以下代码将在SQL Server 2008R2上打印当前年份的所有日期Tsql 在SQL Server 2008R2上打印当前年份的所有日期,tsql,sql-server-2008,Tsql,Sql Server 2008,以下代码将在SQL Server 2008R2上打印当前年份的所有日期 with x (dy, yr) as ( select dy, year (dy) yr from ( select getdate () - datepart (dy, getdate ()) + 1 dy -- the first date of the current year ) tmp1 union all select dateadd (dd, 1, dy), yr from x
with x (dy, yr)
as (
select dy, year (dy) yr
from (
select getdate () - datepart (dy, getdate ()) + 1 dy
-- the first date of the current year
) tmp1
union all
select dateadd (dd, 1, dy), yr
from x
where year (dateadd (dd, 1, dy)) = yr
)
select x.dy
from x
option (maxrecursion 400)
但有几点我无法理解
但是,处理器如何知道语句何时完成 这里要处理的是一个递归CTE。你应该知道它是如何工作的 基本上
- 它从定位部分(第一个选择,UNION ALL的左侧部分)获取第一行集
- 该行集在第二次选择(UNION ALL的右侧部分)中的别名为
,称为递归部分x
- 递归部分基于
生成另一行集,该行集在下一次迭代中成为新的x
。也就是说,不初始x
和最后一个结果集的组合行集将成为新的x
,但仅是最后一个结果集x
- 针对新的
,再次重复上一步,循环继续,直到其中一个为真:x
- 另一次迭代不产生结果集
- 已达到最大递归限制
- 第一个SELECT生成一行,其中包含今年的1月1日(日期),这将成为第一个
表x
- 对于
的每一行,如果属于同一年,则第二次选择将生成一行,其中包含相应的下一个日期。因此,递归部分的第一次迭代有效地给出了1月2日。根据上述描述,结果集成为新的x
x
- 下面的迭代结果是1月3日,下一次迭代产生第4次,以此类推
- 如果MAXRECURSION选项值安全地允许我们到达
包含12月31日的时刻,那么另一次迭代将显示第二天实际上属于不同的一年。这将导致生成一个空行集,这反过来将导致递归CTE的执行终止x
- 这不是答案,这只是编写sql的另一种方式。安德烈M给了你一个冷静的回答,你应该相信他回答正确
;with x (dy)
as (
select dateadd(year, datediff(year, 0, getdate()), 0) dy
union all
select dy + 1
from x
where year (dy) = year(dy+1)
)
select x.dy
from x
option (maxrecursion 400)
“处理器”不知道语句何时完成,但它只知道“退出条件”(
year(…)!=yr
)尚未满足,因此它知道需要继续…是的。。。返回条件是隐式的,这是一个尾部递归,不是吗?是的,很明显。我不知道这种递归有它自己的名字,所以我必须查找术语。谢谢你的提问。:)这里的语法有点违反直觉。我认为返回时会更新这些值。但事实证明,这些值是在途中更新和打印的,返回时什么也不会发生。许多thx的链接和详细的答案。它似乎绝对违反直觉,我也第一次试图理解它。部分原因可能是因为他们必须使其尽可能类似于基于集合的操作。无论如何,一旦我意识到在CTE中,它的别名总是只指返回的最后一个(部分)结果集,一切都会很快到位。thx…当然有很多方法可以获得今年的第一个日期…但是你认为你的答案更快,递归参数更少吗?你把它贴在这里肯定是有原因的,不,但是它使用的资源更少。您正在为每一行选择年份,这是不必要的。它还减少了一天中的时间,这可能会由于各种原因导致并发症。“减少时间”…对不起,我不明白