如何在SQL Server中生成从给定开始日期到结束日期的5分钟间隔数据?
输出应为:如何在SQL Server中生成从给定开始日期到结束日期的5分钟间隔数据?,sql,sql-server,Sql,Sql Server,输出应为: DECLARE @start DATETIME DECLARE @end DATETIME SET @start = '2015-01-01 00:00:00'; SET @end = '2015-03-05 00:00:00'; 递归CTE是一种简单的解决方案: 2015-01-01 00:05:00 2015-01-01 00:10:00 2015-01-01 00:15:00 2015-01-01 00:20:00 2015-01-01 00:25:00 . . . t
DECLARE @start DATETIME
DECLARE @end DATETIME
SET @start = '2015-01-01 00:00:00';
SET @end = '2015-03-05 00:00:00';
递归CTE是一种简单的解决方案:
2015-01-01 00:05:00
2015-01-01 00:10:00
2015-01-01 00:15:00
2015-01-01 00:20:00
2015-01-01 00:25:00
.
.
.
till the end date
或者另一个:
with dates as (
select @start as dte
union all
select dateadd(minute, 5, dte)
from dates
where dte < @end
)
select *
from dates
option (maxrecursion 0);
CTE包含的数字范围为1到65536。然后,对于每个数字,我们将添加从@start date到@end date的数字*5分钟。如果对助手函数打开。我经常使用参数驱动的表值函数 作为TVF,它很容易在交叉应用中使用 范例 返回 如果感兴趣的话,函数
我个人建议计算一下。它们比递归的公共表表达式快得多,因为它们不是RDBMS不擅长的递归表达式。尤其是当你有很多行的时候
CREATE FUNCTION [dbo].[tvf-Date-Range] (@R1 datetime,@R2 datetime,@Part varchar(10),@Incr int)
Returns Table
Return (
with cte0(M) As (Select 1+Case @Part When 'YY' then DateDiff(YY,@R1,@R2)/@Incr When 'QQ' then DateDiff(QQ,@R1,@R2)/@Incr When 'MM' then DateDiff(MM,@R1,@R2)/@Incr When 'WK' then DateDiff(WK,@R1,@R2)/@Incr When 'DD' then DateDiff(DD,@R1,@R2)/@Incr When 'HH' then DateDiff(HH,@R1,@R2)/@Incr When 'MI' then DateDiff(MI,@R1,@R2)/@Incr When 'SS' then DateDiff(SS,@R1,@R2)/@Incr End),
cte1(N) As (Select 1 From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N)),
cte2(N) As (Select Top (Select M from cte0) Row_Number() over (Order By (Select NULL)) From cte1 a, cte1 b, cte1 c, cte1 d, cte1 e, cte1 f, cte1 g, cte1 h ),
cte3(N,D) As (Select 0,@R1 Union All Select N,Case @Part When 'YY' then DateAdd(YY, N*@Incr, @R1) When 'QQ' then DateAdd(QQ, N*@Incr, @R1) When 'MM' then DateAdd(MM, N*@Incr, @R1) When 'WK' then DateAdd(WK, N*@Incr, @R1) When 'DD' then DateAdd(DD, N*@Incr, @R1) When 'HH' then DateAdd(HH, N*@Incr, @R1) When 'MI' then DateAdd(MI, N*@Incr, @R1) When 'SS' then DateAdd(SS, N*@Incr, @R1) End From cte2 )
Select RetSeq = N+1
,RetVal = D
From cte3,cte0
Where D<=@R2
)
解释一下这是什么?
DECLARE @start DATETIME = '2015-01-01 00:00:00';
DECLARE @end DATETIME = '2015-03-05 00:00:00';
Select *
From [dbo].[tvf-Date-Range](@start,@end,'mi',5)
RetSeq RetVal
1 2015-01-01 00:00:00.000
2 2015-01-01 00:05:00.000
3 2015-01-01 00:10:00.000
4 2015-01-01 00:15:00.000
---
18143 2015-03-04 23:50:00.000
18144 2015-03-04 23:55:00.000
18145 2015-03-05 00:00:00.000
CREATE FUNCTION [dbo].[tvf-Date-Range] (@R1 datetime,@R2 datetime,@Part varchar(10),@Incr int)
Returns Table
Return (
with cte0(M) As (Select 1+Case @Part When 'YY' then DateDiff(YY,@R1,@R2)/@Incr When 'QQ' then DateDiff(QQ,@R1,@R2)/@Incr When 'MM' then DateDiff(MM,@R1,@R2)/@Incr When 'WK' then DateDiff(WK,@R1,@R2)/@Incr When 'DD' then DateDiff(DD,@R1,@R2)/@Incr When 'HH' then DateDiff(HH,@R1,@R2)/@Incr When 'MI' then DateDiff(MI,@R1,@R2)/@Incr When 'SS' then DateDiff(SS,@R1,@R2)/@Incr End),
cte1(N) As (Select 1 From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N)),
cte2(N) As (Select Top (Select M from cte0) Row_Number() over (Order By (Select NULL)) From cte1 a, cte1 b, cte1 c, cte1 d, cte1 e, cte1 f, cte1 g, cte1 h ),
cte3(N,D) As (Select 0,@R1 Union All Select N,Case @Part When 'YY' then DateAdd(YY, N*@Incr, @R1) When 'QQ' then DateAdd(QQ, N*@Incr, @R1) When 'MM' then DateAdd(MM, N*@Incr, @R1) When 'WK' then DateAdd(WK, N*@Incr, @R1) When 'DD' then DateAdd(DD, N*@Incr, @R1) When 'HH' then DateAdd(HH, N*@Incr, @R1) When 'MI' then DateAdd(MI, N*@Incr, @R1) When 'SS' then DateAdd(SS, N*@Incr, @R1) End From cte2 )
Select RetSeq = N+1
,RetVal = D
From cte3,cte0
Where D<=@R2
)
DECLARE @StartDate datetime2(0) = '20200401',
@EndDate datetime2(0) = '20200501';
WITH N AS(
SELECT N
FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL))N(N)),
Tally AS(
SELECT TOP ((DATEDIFF(MINUTE,@StartDate, @EndDate) / 5) +1)
ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) -1 AS I
FROM N N1, N N2, N N3, N N4, N N5) --up to 100,000 rows, add for cross joins for more rows
SELECT DATEADD(MINUTE, I*5, @StartDate) AS DateAndTime
FROM Tally;