SQL Query基于while循环

时间:2011-07-22 18:35:49

标签: sql tsql select while-loop

我正在尝试使用while循环构造一个sql查询,该循环在每次迭代时将日期时间增加一分钟,然后根据时间生成一个select语句:

declare @dt datetime
set @dt = '2011-7-21'
while @dt < '2011-7-22'
begin
    select Count(*) From Actions Where Timestamp = @dt
    set @dt = DATEADD(mi, 1, @dt)
end

查询按预期工作,除了while循环的每次迭代似乎完全产生一个新查询,而不是简单地产生一个新行。有没有办法构造它,以便它的单个查询和每一行是由循环的增量生成的? 我相信这是因为select语句在循环中,但我不确定如何以不同的方式构造它。

编辑 - 这是我用临时表创建的,但速度很慢。也许有更快的方法?如果不是那么好,至少这个有效:

create table #temp 
(
  [DT] datetime not null,
  [Total] int not null
)

declare @dt datetime
declare @result int
set @dt = '2011-7-21'
while @dt < '2011-7-22'
begin
    set @result = Count(*) From Actions Where Timestamp = @dt
    insert #temp ([DT],[Total]) values (@dt, @result)
    set @dt = DATEADD(mi, 1, @dt)
end

select * from #temp;

drop table #temp; 

2 个答案:

答案 0 :(得分:1)

使用数字表的一种方法

declare @dt datetime
set @dt = '2011-07-21'

select DATEADD(mi, number, @dt) 
from master..spt_values
where type = 'P'
and DATEADD(mi, number, @dt)  < '2011-07-22'

如果您有自己的号码表,请使用

有关详细信息,请参阅此处http://wiki.lessthandot.com/index.php/Date_Ranges_Without_Loops

你完整的查询就像

DECLARE @dt DATETIME
SET @dt = '2011-07-21'

SELECT x.SomeTime,y.TheCount FROM 
(SELECT DATEADD(mi, number, @dt) as SomeTime FROM master..spt_values
WHERE TYPE = 'P'
AND DATEADD(mi, number, @dt)  < '2011-07-22') x
LEFT JOIN (
    SELECT TIMESTAMP, COUNT(*) AS TheCount
    FROM Actions
    GROUP BY TIMESTAMP
) AS y
ON x.SomeTime = dateadd(mi, datediff(mi, 0, y.Timestamp)+0, 0)

答案 1 :(得分:1)

如果您有一个数字表(从0到100万或其他),这相对简单:

SELECT *
FROM Numbers AS n
LEFT JOIN (
    SELECT Timestamp, COUNT(*) AS Ct
    FROM Actions
    GROUP BY Timestamp
) AS ActionSummary
    ON ActionSummary.Timestamp = DATEADD(mi, n.Number, '2011-07-21')
WHERE DATEADD(mi, n.Number, '2011-07-21') < '2011-07-22'
ORDER BY DATEADD(mi, n.Number, '2011-07-21')

无需循环。

有优化方法,但这应该是可以理解的。

另请注意,时间戳不能有任何秒或几分之一秒才能生效(原始版本也存在此问题)。