我有一张StartTimes和EndTimes表
我希望在每个开始和结束时间之间每15分钟递增1行。
像
这样的东西SELECT StartTime, DATEDIFF(mi, StartTime, EndTime) / 15 AS Offset FROM myTable
CROSS APPLY
-- put something in here to split each row into (EndTime - StartTime) / 15 rows
我想我可以使用SQL OVER函数......但是无法解决这个问题。
答案 0 :(得分:1)
在您需要生成不存在的行的情况下,创建一个数字表会很有帮助,它只包含一堆编号为1,2,3等的行。例如,这会创建一个0到99之间的数字表:
create table ids ( id int )
declare @id int
set @id = 0
while @id < 100
begin
insert ids values (@id)
set @id = @id + 1
end
然后在这个数字表上构建,就像连接原始表一样简单,基于id
的限制小于生成的15分钟周期数:
select
DATEADD(mi, id * 15, StartTime) AS StartTime,
DATEADD(mi, (id + 1) * 15, StartTime) AS EndTime
from
MyTable T
join
ids I on I.id < DATEDIFF(mi, StartTime, EndTime) / 15
请注意,上述查询有两个假设:
ids
表更大)。答案 1 :(得分:1)
您也可以使用resurive CTE来避免创建辅助表:
WITH "CTE"
AS
(
SELECT "id", "starttime" FROM "data"
UNION ALL
SELECT "id", DATEADD( MINUTE, 15, "starttime" )
FROM "CTE"
WHERE "starttime" < ( SELECT "endtime" FROM "data" AS D2 WHERE D2."id" = CTE."id" )
)
SELECT * FROM "CTE"
ORDER BY "ID"
请参阅SQL-Fiddle-Demo!
以上查询还假设数据表中的开始和结束时间组合的差异可以被15整除。
我已经编辑了查询以使用不能被15整除的日期时间 - 如果您选择的15分钟间隔不适合最后计算的间隔,它将被拒绝:
WITH "CTE"
AS
(
SELECT "id", "starttime" FROM "data"
UNION ALL
SELECT "id", DATEADD( MINUTE, 15, "starttime" )
FROM "CTE"
WHERE "starttime" <= ( SELECT DATEADD( MINUTE, -15, "endtime" ) FROM "data" AS D2 WHERE D2."id" = CTE."id" )
)
SELECT * FROM "CTE"
ORDER BY "ID"
如果您想在结果中拒绝最后一个时间戳(在小提琴演示id 2, timestamp "12:00:00"
中),只需将<=
更改为<
即可。如果您使用半开放间隔工作,这也是相关的。