嵌套的WHILE循环 - SQL Server 2000

时间:2016-07-12 18:04:30

标签: sql sql-server loops while-loop sql-server-2000

在SQL Server 2000中,我希望能够列出2个日期之间的所有日期,包括每天的小时数,所以如果我有@fromdate = 2016-07-01 00:00:00@todate = 2016-07-05 00:00:00,那么我需要一个列表:

2016-07-01 00:00:00
2016-07-01 01:00:00
2016-07-01 02:00:00
2016-07-01 03:00:00
2016-07-01 04:00:00
...
2016-07-04 23:00:00
2016-07-05 00:00:00

现在这个查询的工作已经完成了一半:

declare @fromdate as datetime
declare @todate as datetime

set @FromDate = '2016-07-11 00:00:00.000'
set @ToDate = '2016-07-21 00:00:00.000'

declare @i int, @j int

set @i = convert(int, @todate - @fromdate)
set @j = 0

while @i >= 0
begin
  while @j < 24
  begin
     select dateadd(hour, @j, @ToDate - @i) as date, @j as Hour
     set @j = @j + 1
  end

  set @i = @i - 1
end

它会在第一天返回每小时分组,但不会跳到第二天。如果我禁用内部while循环,外部循环可以正常工作而无需数小时。欢迎提出任何建议,请记住它是SQL Server 2000,因此没有任何高级版本可以使用。

5 个答案:

答案 0 :(得分:1)

将您的问题视为学术问题,这就是您的代码无效的原因:

内循环完成后,您需要将@j重置为零。否则@j保持在“24”并且内部循环永远不会再次执行。

正如其他人所指出的那样,还有其他可能更好的方法来做你想做的事。

答案 1 :(得分:0)

我认为你可以做一些简单的事情。我没有检查dateadd sintaxis,但每次只增加1小时,直到达到目标日期

The PHP exe file you specified did not run correctly:
C:\xampp\php\php.exe

The php.ini used by your command-line PHP is: C:\xampp\php\php.ini

Program Output:
Warning: PHP Startup: PDO: Unable to initialize module
Module compiled with module API=20090626
PHP    compiled with module API=20131226
These options need to match
 in Unknown on line 0

答案 2 :(得分:0)

这将根据您的范围在表格中按顺序为您提供所需的日期。

create table #dates(
dates datetime)

declare @fromdate as datetime
declare @todate as datetime

set @FromDate = '2016-07-11 00:00:00.000'
set @ToDate = '2016-07-21 00:00:00.000'

declare @ct int 
set @ct = datediff(hour,@FromDate,@ToDate)

while @ct > 0
  begin
    insert into #dates (dates)
    select dateadd(hour,@ct,@FromDate)
    set @ct = @ct - 1
  end

select * from #dates
--RESULTS
2016-07-21 00:00:00.000
2016-07-20 23:00:00.000
2016-07-20 22:00:00.000
2016-07-20 21:00:00.000
2016-07-20 20:00:00.000
2016-07-20 19:00:00.000
2016-07-20 18:00:00.000
2016-07-20 17:00:00.000
2016-07-20 16:00:00.000
....etc...

答案 3 :(得分:0)

要添加,您可能还想使用表变量来加快速度并获得一个结果集:

declare @table table (DateHour datetime, Hour int)
declare @fromdate as datetime
declare @todate as datetime

set @FromDate = '2016-07-11 00:00:00.000'
set @ToDate = '2016-07-21 00:00:00.000'

declare @i int, @j int

set @i = convert(int, @todate - @fromdate)
set @j = 0
while @i >= 0
begin
  while @j <24
  begin
     insert @table
     values (dateadd(hour, @j, @ToDate - @i), @j) --as Hour
     set @j=@j+1
  end
set @j=0
set @i=@i-1
end
select * from @table

答案 4 :(得分:0)

为了演示计数表概念,我把它放在一起。这将在sql 2000中正常工作。第一步是创建持久性计数表。这只需要在您第一次使用这种表时完成。在更高版本的sql中,我会以不同的方式创建它,但它仍然有效。如果你想要,你甚至可以添加一个触发器来禁止插入或删除,这样你就可以确保没有间隙。

create Table MyTally
(
    N int identity(1,1) 
)
GO

insert MyTally
DEFAULT VALUES
go 10000 --This will cause the previous batch to loop that many times.

现在我们有一个包含10,000个递增值的表,我们可以使用它。

declare @fromdate as datetime
declare @todate as datetime

set @FromDate = '2016-07-11 00:00:00.000'
set @ToDate = '2016-07-21 00:00:00.000'

select dateadd(hour, x.N - 1, DATEADD(day, t.N - 1, @FromDate))
from cteTally t
cross join 
(
    select N
    from cteTally
    where N <= 24
)x
where t.N <= DATEDIFF(day, @FromDate, @todate) + 1

这将创建这两个日期之间的11天所需的264行。