如何在T-SQL中生成两个日期之间的分钟间隔?

时间:2016-07-20 11:34:56

标签: sql-server tsql sql-server-2014

我有一个startTime和endTimes表。我需要在几分钟内生成这两个日期之间的间隔表。以下是一些示例数据:

declare @intervalMinutes int = 10
declare @myDates table (
myId int primary key identity,
startTime datetime,
endTime datetime
)

insert @myDates (startTime, EndTime) values ('2016-07-10 08:00','2016-07-10 09:00')
insert @myDates (startTime, EndTime) values ('2016-07-12 10:00','2016-07-12 12:00')
insert @myDates (startTime, EndTime) values ('2016-07-14 12:30','2016-07-14 14:30')

我希望看到每个myId一组间隔@intervalMinutes的日期。

因此,如果我们将@intervalMinutes设置为10,那么我会在第一行中看到2016-07-10 08:002016-07-10 09:00之间的6个日期的列表,以10分钟为增量。

3 个答案:

答案 0 :(得分:4)

数字/理货表可以像戈登提到的那样做。但是,我使用UDF来创建动态日期范围。

例如

Select * from [dbo].[udf-Create-Range-Date]('2016-07-10 08:00','2016-07-10 09:00','MI',10)

返回

RetVal
2016-07-10 08:00:00.000
2016-07-10 08:10:00.000
2016-07-10 08:20:00.000
2016-07-10 08:30:00.000
2016-07-10 08:40:00.000
2016-07-10 08:50:00.000
2016-07-10 09:00:00.000

UDF

CREATE FUNCTION [dbo].[udf-Create-Range-Date] (@DateFrom datetime,@DateTo datetime,@DatePart varchar(10),@Incr int)

Returns 
@ReturnVal Table (RetVal datetime)

As
Begin
    With DateTable As (
        Select DateFrom = @DateFrom
        Union All
        Select Case @DatePart
               When 'YY' then DateAdd(YY, @Incr, df.dateFrom)
               When 'QQ' then DateAdd(QQ, @Incr, df.dateFrom)
               When 'MM' then DateAdd(MM, @Incr, df.dateFrom)
               When 'WK' then DateAdd(WK, @Incr, df.dateFrom)
               When 'DD' then DateAdd(DD, @Incr, df.dateFrom)
               When 'HH' then DateAdd(HH, @Incr, df.dateFrom)
               When 'MI' then DateAdd(MI, @Incr, df.dateFrom)
               When 'SS' then DateAdd(SS, @Incr, df.dateFrom)
               End
        From DateTable DF
        Where DF.DateFrom < @DateTo
    )

    Insert into @ReturnVal(RetVal) Select DateFrom From DateTable option (maxrecursion 32767)

    Return
End

-- Syntax Select * from [dbo].[udf-Create-Range-Date]('2016-10-01','2020-10-01','YY',1) 
-- Syntax Select * from [dbo].[udf-Create-Range-Date]('2016-10-01','2020-10-01','DD',1) 
-- Syntax Select * from [dbo].[udf-Create-Range-Date]('2016-10-01','2016-10-31','MI',15) 
-- Syntax Select * from [dbo].[udf-Create-Range-Date]('2016-10-01','2016-10-02','SS',1) 

答案 1 :(得分:2)

您可以使用这样的递归查询:

declare @intervalMinutes int = 10
declare @myDates table (
myId int primary key identity,
startTime datetime,
endTime datetime
)

DECLARE @startTime DATETIME = '2016-07-10 08:00'
DECLARE @endTime DATETIME = '2016-07-10 09:00'

;WITH CTE AS
(
    SELECT  @startTime st
    UNION   ALL
    SELECT  dateadd(MINUTE,@intervalMinutes,st) st
    FROM    cte
    where   dateadd(MINUTE,@intervalMinutes,st) < @endTime
)
INSERT INTO @myDates(startTime,endTime)
SELECT st,dateadd(MINUTE,@intervalMinutes,st) FROM cte

SELECT  * FROm @myDates

答案 2 :(得分:1)

数字表可以解决您的问题。假设你不需要超过几千行,那么这应该有效:

with n as (
      select row_number() over (order by (select null)) - 1 as n
      from master.spt_values
     )
select d.*,
       dateadd(minute, n.n * @intervalMinutes, d.startTime)
from @myDates d join
     n
     on dateadd(minute, n.n * @intervalMinutes, d.startTime) <= d.endTime;