我正在尝试在一个表上创建一个查询,该表为具有开始时间和结束时间的人提供了多个条目,例如:
名,STARTIME,结束时间
('richard','2010-04-21 08:01:15','2010-04-21 08:06:15'),
('bill','2010-04-21 08:07:45','2010-04-21 08:11:15')
我需要做的是创建一个报告,显示每个5分钟间隔内每个条目的秒数,例如
名称,时间,秒
------------------
理查德,8:00225
理查德,8:05,75
法案,8:05135
纸币,8:10,75
因此查询必须创建这些间隔,然后计算每条记录的秒数,以显示该间隔中的总秒数。任何帮助将不胜感激。
答案 0 :(得分:1)
这是一个迭代解决方案,可以在开始时间在结束时间之前的任何时间段内工作。您没有指定是否要保留日期组件,以便在不同日期的当天早上8点报告时间间隔,或者是否要对它们进行分组。通过将我的解决方案中的time_bucket列转换为varchar然后将substring转换为varchar,然后将该varchar分组,然后将该组中的秒数相加,就可以很容易地丢弃日期组件。
如果您正在按时间段进行分析,那么您应该有一个时间桶维度表,类似于Lieven在其解决方案中提出的建议。这解决了你的基数问题。没有它,你必须做这样的事情:
create table #results
( name varchar(20) not null, time_bucket datetime not null, seconds int not null )
declare @name varchar(20), @startTime datetime, @endTime datetime, @timeBucket datetime, @secondsInBucket int
declare dataCur cursor for select * from source_data
open dataCur
fetch next from dataCur into @name, @startTime, @endTime
while @@fetch_status = 0
begin
set @timeBucket = convert(datetime, convert(varchar(14), @startTime, 120) + convert(varchar(2), (datepart(mi, @startTime) / 5) * 5), 120)
while @timeBucket < @endTime
begin
set @secondsInBucket = case
when @timeBucket < @startTime then datediff(ss, @startTime, dateadd(mi, 5, @timeBucket))
when @endTime < dateadd(mi, 5, @timeBucket) then datediff(ss, @timeBucket, @endTime)
else 300
end
insert into #results values (@name, @timeBucket, @secondsInBucket)
set @timeBucket = dateadd(mi, 5, @timeBucket)
end
fetch next from dataCur into @name, @startTime, @endTime
end
close dataCur
deallocate dataCur
select * from #results
答案 1 :(得分:0)
以下脚本可以帮助您入门。
虽然有一些警告提示
SQL脚本
DECLARE @People TABLE (
Name VARCHAR(32)
, StartTime DATETIME
, EndTime DATETIME
)
DECLARE @MinHour INTEGER
DECLARE @MaxHour INTEGER
DECLARE @Times TABLE (
Hour INTEGER
, Minute INTEGER
)
INSERT INTO @People
SELECT 'richard', '2010-04-21 08:01:15', '2010-04-21 08:06:15'
UNION ALL SELECT 'bill' , '2010-04-21 08:07:45', '2010-04-21 08:11:15'
SELECT @MinHour = MIN(DATEPART(hh, StartTime))
, @MaxHour = MAX(DATEPART(hh, EndTime))
FROM @People
WHILE @MinHour < @MaxHour + 1
BEGIN
INSERT INTO @Times
SELECT @MinHour, 0
UNION ALL SELECT @MinHour, 5
UNION ALL SELECT @MinHour, 10
UNION ALL SELECT @MinHour, 15
UNION ALL SELECT @MinHour, 20
UNION ALL SELECT @MinHour, 25
UNION ALL SELECT @MinHour, 30
UNION ALL SELECT @MinHour, 35
UNION ALL SELECT @MinHour, 40
UNION ALL SELECT @MinHour, 45
UNION ALL SELECT @MinHour, 50
UNION ALL SELECT @MinHour, 55
SET @MinHour = @MinHour + 1
END
SELECT p.Name
, t.Hour
, t.Minute
, CASE WHEN DATEPART(mi, p.EndTime) - DATEPART(mi, p.EndTime) % 5 = t.Minute
THEN 60 * (DATEPART(mi, p.EndTime) % 5) + DATEPART(ss, p.EndTime)
ELSE 300 - 60 * (DATEPART(mi, p.StartTime) % 5) - DATEPART(ss, p.StartTime)
END
FROM @People p
INNER JOIN @Times t ON DATEPART(hh, p.StartTime) = t.Hour
AND DATEPART(hh, p.EndTime) = t.Hour
AND DATEPART(mi, p.StartTime) - DATEPART(mi, p.StartTime) % 5 <= t.Minute
AND DATEPART(mi, p.EndTime) - DATEPART(mi, p.EndTime) % 5 >= t.Minute
ORDER BY
p.Name