带有日期循环的 SQL [关闭]
Posted
技术标签:
【中文标题】带有日期循环的 SQL [关闭]【英文标题】:SQL with Date LOOP [closed] 【发布时间】:2020-12-25 17:17:43 【问题描述】:我一直在尝试编写一个查询,该查询返回 36 个月的每个月的倒数第二天,并且该查询应该自动返回 36 个月的记录。
例如;如 20201230 为 12 月,20210130 为 1 月,20210228 为 2 月(不包括 2 月)。然后,我将以这种方式更新表中列中指定的日期。
它应该就像一个循环,或者我可以使用光标来做吗?顺便说一句,日期应该是参数化的提前感谢您的帮助
【问题讨论】:
您说“我一直在尝试”,在这种情况下,我们真正受益于看到“您一直在尝试的内容”。您在下面有 3 个答案 - 他们中的任何一个都为您解决了问题吗?如果是这样,请考虑接受一个。 【参考方案1】:更好的方法是使用计数函数、dateadd 和 eomonth。
数字函数
create function [dbo].[fnNumbers](
@zero_or_one bit,
@n bigint)
returns table with schemabinding as return
with n(n) as (select null from (values (1),(2),(3),(4)) n(n))
select 0 n where @zero_or_one = 0
union all
select top(@n) row_number() over(order by (select null)) n
from n na, n nb, n nc, n nd, n ne, n nf, n ng, n nh,
n ni, n nj, n nk, n nl, n nm, n np, n nq, n nr;
查询
declare
@start_dt date='2020-12-25';
select dateadd(day, -1, eomonth(@start_dt, fn.n)) penult_dt
from dbo.fnNumbers(0, 35) fn;
【讨论】:
【参考方案2】:这就是你要找的东西?
DECLARE @Start DATE='2020-12-25'
;WITH CTE
as
(
SELECT 1 Seq, DATEADD(DAY,-DAY(@Start),DATEADD(MONTH,1,@Start)) Dt
UNION ALL
SELECT Seq+1, DATEADD(DAY,-DAY(@Start),DATEADD(MONTH,Seq+1,@Start)) FROM CTE WHERE Seq+1 <37
)
SELECT FORMAT(Dt,'yyyyMMdd') Dates FROM CTE
【讨论】:
【参考方案3】:您需要当前月的倒数第二天以及接下来的 36 个月。这是一个使用递归查询的选项:
with cte as (
select dateadd(month, 1, datefromparts(year(getdate()), month(getdate()), 1)) as dt
union all
select dateadd(month, 1, dt) from cte where dt < dateadd(month, 36, getdate())
)
select dt, dateadd(day, -2, dt) as dt_penultimate
from cte
这个想法是使用递归查询从下个月开始生成一系列开始。然后在外部查询中,我们只是将每个日期偏移 2 天。
您可以根据需要将getdate()
替换为查询参数。
如果必须生成超过 100 个月的跨度,则需要在查询的最后添加 option(maxrecursion 0)
。
Demo on DB Fiddle:
dt | dt_倒数第二个 :--------- | :------------- 2021-01-01 | 2020-12-30 2021-02-01 | 2021-01-30 2021-03-01 | 2021-02-27 2021-04-01 | 2021-03-30 ...【讨论】:
以上是关于带有日期循环的 SQL [关闭]的主要内容,如果未能解决你的问题,请参考以下文章