如何根据日期以一个月为增量填充 table
How can I populate a table in one month increments based on a date
我需要根据另一个 table 的输入日期加载一个 table,该输入日期介于一个月的第一天和该月的最后一天之间。我需要将负载减少为从当前月份起 1 个月的 1 个月的记录,然后从当前月份开始减少 2 个月,依此类推。
我尝试过 CTE,使用游标并手动更改 datediff 参数。最后一种方法有效,但我想动态加载 table
Declare @StartDt as datetime = (SELECT FORMAT(DATEADD(s,0,DATEADD(mm, DATEDIFF(m,0,GETDATE())-1,0)),'MM/dd/yyyy'));
Declare @endDt as datetime = EOMONTH(@StartDt);
SELECT useruid,
userfullname,
sum(totaltime)SumTime,
@StartDt as StartDate,
@EndDt as EndDate
FROM Table_1.tbl
WHERE ENTRYDATE between @StartDt and @EndDt
group by useruid, USERFULLNAME;
我正在将其插入另一个 table。通过手动将 Startdt 变量中的 -1 更改为 -2 等,我没有遇到任何问题。我想知道是否可以在加载另一个 table 时动态更改它。
同样,我加载 table 没有问题。我只想知道是否有更有效的方法,因为我必须倒退 100 个月。
您可以使用动态 SQL 动态编写您的 @StartDt 声明语句。
我把你的代码放在 while 循环中,它会 运行 100 次。 (回溯 100 个月):
declare @int int = 0
while @int > -100
begin
set @int= @int -1
declare @str varchar(max)
set @str = 'declare @StartDt as datetime = (SELECT FORMAT(DATEADD(s,0,DATEADD(mm, DATEDIFF(m,0,GETDATE())'+cast(@int as varchar(10))+',0)),''MM/dd/yyyy''))'
execute (@str)
Declare @endDt as datetime = EOMONTH(@StartDt)
SELECT useruid,
userfullname,
sum(totaltime)SumTime,
@StartDt as StartDate,
@EndDt as EndDate
FROM Table_1.tbl
WHERE ENTRYDATE between @StartDt and @EndDt
group by useruid, USERFULLNAME
end
一种方法是递归 CTE:
with dates as (
select datefromparts(year(getdate()), month(getdate()), 1) as dte
union all
select dateadd(month, -1, dte)
from dates
where dte > ? -- how far back do you want to go?
)
select t.useruid, t.userfullname, sum(t.totaltime) as SumTime,
d.dte as StartDate,
dateadd(month, 1, d.dte) as EndDate
from dates d JOIN
Table_1.tbl t
on t.ENTRYDATE >= d.dte AND
t.ENTRYDATE < dateadd(month, 1, d.dte)
group by t.useruid, t.USERFULLNAME, d.dte;
您不需要(明确的)循环或游标。
注意:您似乎出于某种原因要从日期中减去一秒。我不明白为什么。您可能需要此逻辑作为结束日期,但最好使用 on
子句中的不等式(例如,这样您就不必担心毫秒)。
我需要根据另一个 table 的输入日期加载一个 table,该输入日期介于一个月的第一天和该月的最后一天之间。我需要将负载减少为从当前月份起 1 个月的 1 个月的记录,然后从当前月份开始减少 2 个月,依此类推。
我尝试过 CTE,使用游标并手动更改 datediff 参数。最后一种方法有效,但我想动态加载 table
Declare @StartDt as datetime = (SELECT FORMAT(DATEADD(s,0,DATEADD(mm, DATEDIFF(m,0,GETDATE())-1,0)),'MM/dd/yyyy'));
Declare @endDt as datetime = EOMONTH(@StartDt);
SELECT useruid,
userfullname,
sum(totaltime)SumTime,
@StartDt as StartDate,
@EndDt as EndDate
FROM Table_1.tbl
WHERE ENTRYDATE between @StartDt and @EndDt
group by useruid, USERFULLNAME;
我正在将其插入另一个 table。通过手动将 Startdt 变量中的 -1 更改为 -2 等,我没有遇到任何问题。我想知道是否可以在加载另一个 table 时动态更改它。
同样,我加载 table 没有问题。我只想知道是否有更有效的方法,因为我必须倒退 100 个月。
您可以使用动态 SQL 动态编写您的 @StartDt 声明语句。
我把你的代码放在 while 循环中,它会 运行 100 次。 (回溯 100 个月):
declare @int int = 0
while @int > -100
begin
set @int= @int -1
declare @str varchar(max)
set @str = 'declare @StartDt as datetime = (SELECT FORMAT(DATEADD(s,0,DATEADD(mm, DATEDIFF(m,0,GETDATE())'+cast(@int as varchar(10))+',0)),''MM/dd/yyyy''))'
execute (@str)
Declare @endDt as datetime = EOMONTH(@StartDt)
SELECT useruid,
userfullname,
sum(totaltime)SumTime,
@StartDt as StartDate,
@EndDt as EndDate
FROM Table_1.tbl
WHERE ENTRYDATE between @StartDt and @EndDt
group by useruid, USERFULLNAME
end
一种方法是递归 CTE:
with dates as (
select datefromparts(year(getdate()), month(getdate()), 1) as dte
union all
select dateadd(month, -1, dte)
from dates
where dte > ? -- how far back do you want to go?
)
select t.useruid, t.userfullname, sum(t.totaltime) as SumTime,
d.dte as StartDate,
dateadd(month, 1, d.dte) as EndDate
from dates d JOIN
Table_1.tbl t
on t.ENTRYDATE >= d.dte AND
t.ENTRYDATE < dateadd(month, 1, d.dte)
group by t.useruid, t.USERFULLNAME, d.dte;
您不需要(明确的)循环或游标。
注意:您似乎出于某种原因要从日期中减去一秒。我不明白为什么。您可能需要此逻辑作为结束日期,但最好使用 on
子句中的不等式(例如,这样您就不必担心毫秒)。