Sql 返回具有给定间隔的有效时隙
我试图通过SQL返回给定时间间隔的开始时间和结束时间之间的所有有效时间段,但我遇到了很大的心理障碍。下面是一些带有一些变量的示例代码,然后是存储每个值的表。变量使用INT,因为最终存储值的数据类型是INT,不能更改Sql 返回具有给定间隔的有效时隙,sql,sql-server-2008,tsql,Sql,Sql Server 2008,Tsql,我试图通过SQL返回给定时间间隔的开始时间和结束时间之间的所有有效时间段,但我遇到了很大的心理障碍。下面是一些带有一些变量的示例代码,然后是存储每个值的表。变量使用INT,因为最终存储值的数据类型是INT,不能更改 DECLARE @StartTime INT = 900 DECLARE @EndTime INT = 2000 DECLARE @CurrentTime INT = 900 DECLARE @Interval INT = 15 DECLARE @Times TABLE (
DECLARE @StartTime INT = 900
DECLARE @EndTime INT = 2000
DECLARE @CurrentTime INT = 900
DECLARE @Interval INT = 15
DECLARE @Times TABLE
(
[Time] INT
)
WHILE (@CurrentTime <= @EndTime)
BEGIN
INSERT INTO @Times VALUES (@CurrentTime)
SET @CurrentTime = @CurrentTime + @Interval
END
预期的结果是:
900
915
930
945
1000
1015
1030
etc.
有什么方法可以做到这一点,通过除以当前值并期望一个余数,还是一种简单的方法来实现期望的结果
谢谢你试试这个
DECLARE @StartTime INT = 900
DECLARE @EndTime INT = 2000
DECLARE @CurrentTime INT = 900
DECLARE @Interval INT = 15
DECLARE @Times TABLE
(
[Time] INT
)
WHILE (@CurrentTime <= @EndTime)
BEGIN
INSERT INTO @Times VALUES (@CurrentTime)
SET @CurrentTime = @CurrentTime + @Interval
IF(RIGHT(@CurrentTime,2) = 60)
SET @CurrentTime = @CurrentTime + 40
END
SELECT * FROM @Times
试试这个
DECLARE @StartTime INT = 900
DECLARE @EndTime INT = 2000
DECLARE @CurrentTime INT = 900
DECLARE @Interval INT = 15
DECLARE @Times TABLE
(
[Time] INT
)
WHILE (@CurrentTime <= @EndTime)
BEGIN
INSERT INTO @Times VALUES (@CurrentTime)
SET @CurrentTime = @CurrentTime + @Interval
IF(RIGHT(@CurrentTime,2) = 60)
SET @CurrentTime = @CurrentTime + 40
END
SELECT * FROM @Times
这有点复杂,但与上面的答案有一些不同:它可以桥接午夜,处理不是60的时间间隔,以7的时间间隔尝试上面的方法,并使用递归CTE来生成数字,而不是WHILE循环 INT数据类型真是太可惜了,TSQL的时间数据类型带来了很多好处。您可以取消辅助函数 MAXRECURSION选项有时会有问题,因为您不能在视图中使用它。。。调用语句必须指定它。若要解决此问题,请将其包装在多语句表值函数中
这有点复杂,但与上面的答案有一些不同:它可以桥接午夜,处理不是60的时间间隔,以7的时间间隔尝试上面的方法,并使用递归CTE来生成数字,而不是WHILE循环 INT数据类型真是太可惜了,TSQL的时间数据类型带来了很多好处。您可以取消辅助函数 MAXRECURSION选项有时会有问题,因为您不能在视图中使用它。。。调用语句必须指定它。若要解决此问题,请将其包装在多语句表值函数中
时间段mod 60………时间段mod 60。。。。。。。。。。。。。
CREATE FUNCTION dbo.ConvertIntToTime (@TimeAsInt INT)
RETURNS TIME
BEGIN
DECLARE @TimeString VARCHAR(4) = RIGHT(REPLICATE('0',4) + CAST(@TimeAsInt AS VARCHAR(4)),4);
RETURN PARSE(LEFT(@TimeString,2) + ':' + RIGHT(@TimeString,2) AS TIME);
END;
GO
CREATE FUNCTION dbo.ConvertTimeToInt (@Time TIME)
RETURNS INT
BEGIN
DECLARE @TimeString VARCHAR(5) = CONVERT(VARCHAR(5), @Time, 108);
RETURN PARSE(LEFT(@TimeString,2) + RIGHT(@TimeString,2) AS INT);
END;
GO
DECLARE @CurrentTime AS INT = 900;
DECLARE @EndTime AS INT = 1700;
DECLARE @Interval AS INT = 10;
DECLARE @CurrentTimeAsTime TIME = dbo.ConvertIntToTime(@CurrentTime);
DECLARE @EndTimeAsTime TIME = dbo.ConvertIntToTime(@EndTime);
WITH CTEGenerateTimes AS
(
SELECT @CurrentTimeAsTime Time
UNION ALL
SELECT DATEADD(MINUTE, @Interval, Time) AS TIME
FROM CTEGenerateTimes
WHERE (@EndTimeAsTime >= @CurrentTimeAsTime AND DATEADD(MINUTE, @Interval, Time) <= @EndTimeAsTime AND DATEADD(MINUTE, @Interval, Time) <> CAST('00:00' AS TIME)) --Range doesn't cross midnight
OR (@EndTimeAsTime < @CurrentTimeAsTime AND DATEADD(MINUTE, @Interval, Time) > @CurrentTimeAsTime AND DATEADD(MINUTE, @Interval, Time) <= CAST('23:59:59' AS TIME)) --Range crosses midnight, portion before midnight
OR (@EndTimeAsTime < @CurrentTimeAsTime AND DATEADD(MINUTE, @Interval, Time) <= @CurrentTimeAsTime AND DATEADD(MINUTE, @Interval, Time) <= @EndTimeAsTime)
)
SELECT dbo.ConvertTimeToInt(t.Time) Time
FROM CTEGenerateTimes t
OPTION (MAXRECURSION 1441)