填补了多年的日期

时间:2016-08-04 15:31:57

标签: sql sql-server

您好我正在尝试在sql server中填写一年中每一分钟的日期时间。我找到了下面的代码,很好地填写了一年的所有日期。我想知道是否有一种简单的方法可以修改日期时间到达分钟。

Code:

declare @datestart date = '2010-1-1',   @dateend date = '2016-10-31'

declare @days int = datediff(d,@datestart,@dateend)

select
    dateadd(d, number, @datestart)
from master..spt_values 
where type='p'
    and number<=@days

5 个答案:

答案 0 :(得分:1)

使用Numbers表..

declare @startdate datetime
set @startdate='20160101'

;with cte(startdate)
as
(select @startdate
)
select b.*from cte c
cross apply
(
select dateadd(minute,n,c.startdate ) as minutes
from numbers n
where dateadd(minute,n,c.startdate) <= DATEADD(yy, DATEDIFF(yy,0,getdate()) + 1, -1)) b

如果你不想要数字表,你可以使用下面的递归CTE ..但是这个版本很慢(在我的系统上花了10秒),当你想要生成超过几年的分钟时,你可能会达到maxrecursion限制。

declare @startdate datetime
set @startdate='20160101'

;With Cte(startdate)
as
(
select @startdate
union all
select dateadd(minute,1,startdate)
from cte
where dateadd(minute,1,startdate)<=DATEADD(yy, DATEDIFF(yy,0,getdate()) + 1, -1)
)
select * from cte option(maxrecursion 0)

两个版本的输出:

2016-01-01 00:01:00.000
2016-01-01 00:02:00.000

答案 1 :(得分:1)

我要递归:

declare @datestart date = '2010-1-1',   @dateend date = '2016-10-31'

;with cte as (select cast(@datestart as datetime) as d union all
              select dateadd(MINUTE,1,d) from cte where d<@dateend)
select * 
  from cte
OPTION (MAXRECURSION 0)

<强> OUPUT

   d
    2010-01-01 00:00:00.000
    2010-01-01 00:01:00.000
    2010-01-01 00:02:00.000
    2010-01-01 00:03:00.000
    2010-01-01 00:04:00.000
    2010-01-01 00:05:00.000
    ...
    2016-10-30 23:58:00.000
    2016-10-30 23:59:00.000
    2016-10-31 00:00:00.000

答案 2 :(得分:1)

     declare @start datetime='1/1/2016 0:0:0' 
     declare @end datetime 
     set @end=DATEADD(year,1,@start)

    ;with cte
    as
    (
    select 
    ROW_NUMBER() OVER(ORDER BY a.name ) AS Row 
    from master..spt_values  a, master..spt_values  b
    )

    select cte.Row , DATEADD(minute,cte.Row,@start ) curr
    from cte
    where DATEADD(minute,cte.Row,@start ) < @end

结果:

    1   2016-01-01 00:01:00.000
    2   2016-01-01 00:02:00.000
    3   2016-01-01 00:03:00.000
    4   2016-01-01 00:04:00.000
    5   2016-01-01 00:05:00.000
    6   2016-01-01 00:06:00.000
    7   2016-01-01 00:07:00.000
    8   2016-01-01 00:08:00.000
    9   2016-01-01 00:09:00.000
    ....

    ...
    527031  2016-12-31 23:51:00.000
    527032  2016-12-31 23:52:00.000
    527033  2016-12-31 23:53:00.000
    527034  2016-12-31 23:54:00.000
    527035  2016-12-31 23:55:00.000
    527036  2016-12-31 23:56:00.000
    527037  2016-12-31 23:57:00.000
    527038  2016-12-31 23:58:00.000
    527039  2016-12-31 23:59:00.000

你可以额外获得更多年份:)(如果需要),或者可能是第二年:)

答案 3 :(得分:0)

使用递归的解决方案非常好,但这应该更快:

;WITH Pass0 as (SELECT * FROM (VALUES (1),(1),(1),(1)) as A(C)),
  Pass1 as (select 1 as C from Pass0 as A, Pass0 as B),--16 rows
  Pass2 as (select 1 as C from Pass1 as A, Pass1 as B),--256 rows  
  Pass3 as (select 1 as C from Pass2 as A, Pass2 as B),--65536 rows
  Pass4 as (select 1 as C from Pass3 as A, Pass3 as B),--65536 rows
  Pass5 as (select 1 as C from Pass4 as A, Pass4 as B),-- 16 Mln Records 
  Numbers AS (SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL))-1 as Numbers FROM Pass5)
SELECT DATEADD(mi,Numbers,@datestart) as Next_Minute 
FROM Numbers
WHERE Numbers <= DATEDIFF(minute,@datestart,@dateend);

答案 4 :(得分:0)

很容易扩展原来的处理分钟的尝试。根据您打算这样做的频率,您可能需要优化您的方法。我想,一个简单的循环足以满足您的需求。

create table #minutes (dt datetime not null);
declare @datestart datetime = '2016-01-01 00:00', @dateend datetime = '2016-01-03 23:59';

while @datestart <= @dateend
begin
    insert into #minutes (dt)
    select dateadd(minute, number, @datestart)
    from master..spt_values 
    where
            type = 'p' and number between 0 and 1439
        and dateadd(minute, number, @datestart) <= @dateend;
    set @datestart = dateadd(minute, 1440, @datestart);
end