问题
I have this code which I'm writing into a stored procedure:
declare @StartTime time
declare @EndTime time
declare @Temp_StartTime time
declare @temp_StartHour int
declare @temp_EndHour int
declare @temp_StartMinute int
declare @temp_EndMinute int
SET @StartTime='22:30:00'
SET @EndTime='00:52:00'
SET @Temp_StartTime=@StartTime
SET @temp_StartHour=DATEPART(HOUR, @StartTime)
SET @temp_EndHour=DATEPART(HOUR, @EndTime)
SET @temp_StartMinute=DATEPART(MI, @StartTime)
SET @temp_EndMinute=DATEPART(MI, @EndTime)
if(@temp_EndMinute>0)
BEGIN
SET @temp_EndHour=@temp_EndHour+1
END
DECLARE @Temp_Table TABLE
(
StartHour int,
StartMinute int,
EndHour int,
EndMinute int,
StartTime time,
EndTime time
)
WHile((@temp_EndHour-@temp_StartHour>=1))
BEGIN
INSERT INTO @Temp_Table
SELECT (DATEPART(HOUR, @Temp_StartTime)) AS StartHour,(DATEPART(MINUTE, @Temp_StartTime)) AS StartMinute,
@temp_StartHour+1 AS EndHour,
0 AS EndMinute, @StartTime as StartTime, @EndTime as EndTime
SET @temp_StartHour=@temp_StartHour+1
SET @Temp_StartTime=DATEADD(HOUR,1,@Temp_StartTime)
if(DATEPART(MI, @Temp_StartTime)!=0)
BEGIN
SET @Temp_StartTime=DATEADD(MI,-@temp_StartMinute,@Temp_StartTime)
END
END
SELECT * FROM @Temp_Table
It works great if you use any time value other than the 00:52:00 example I have up there. For instance, if EndTime was 23:05, the stored procedure works great. I did some research around DATEPART but didn't find anything helpful as to how to get it to calculate midnight at military time properly.
EDIT: When the code runs properly, it calculates the time in how many hours between start and end time and the idea is to store new rows for each hour into the temp table (eventually this is going to be saved to a new table for tracking outages by hour). It works find when I run it with 21:30 to 22:15. I get two rows reflecting 21:00 to 22:00 and 22:00 to 23:00 (this is the logic I want). But throw military midnight in there, and I get no rows returned as the calc won't compute the 00.
I have found examples in my database that show start times of 22:00:0000 and end times of 00:00:00.0000000 and then visa versa. So one way WILL calculate, where start time is 00, but if start time is 21:00:0000 and end time is 00:52:0000 then no dice. I get no rows returned.
回答1:
If I am not missing anything, this is what you could try instead of your loop:
DECLARE
@StartTime time,
@EndTime time;
SET @StartTime = '22:30:00';
SET @EndTime = '00:52:00';
WITH timerange AS (
SELECT
StartTime = CAST(@StartTime AS datetime),
EndTime = DATEADD(
DAY,
CASE WHEN @StartTime > @EndTime THEN 1 ELSE 0 END,
CAST(@EndTime AS datetime)
)
),
hourly AS (
SELECT
n.number,
t.StartTime,
t.EndTime,
HStart = DATEADD(HOUR, DATEDIFF(HOUR, 0, t.StartTime) + n.number , 0),
HEnd = DATEADD(HOUR, DATEDIFF(HOUR, 0, t.StartTime) + n.number + 1, 0)
FROM timerange t
INNER JOIN master..spt_values n
ON n.number BETWEEN 0 AND DATEDIFF(HOUR, t.StartTime, t.EndTime)
WHERE n.type = 'P'
),
hourly2 AS (
SELECT
number,
HStart = CASE WHEN StartTime > HStart THEN StartTime ELSE HStart END,
HEnd = CASE WHEN EndTime < HEnd THEN EndTime ELSE HEnd END
FROM hourly
)
SELECT
StartHour = DATEPART(HOUR , HStart),
StartMinute = DATEPART(MINUTE, HStart),
EndHour = DATEPART(HOUR , HEnd ),
EndMinute = DATEPART(MINUTE, HEnd ),
StartTime = CAST(HStart AS time),
EndTime = CAST(HEnd AS time)
FROM hourly2
ORDER BY number
;
The output produced is this:
StartHour StartMinute EndHour EndMinute StartTime EndTime
----------- ----------- ----------- ----------- ---------------- ----------------
22 30 23 0 22:30:00.0000000 23:00:00.0000000
23 0 0 0 23:00:00.0000000 00:00:00.0000000
0 0 0 52 00:00:00.0000000 00:52:00.0000000
来源:https://stackoverflow.com/questions/10338436/how-to-convert-a-datepart-hour-thats-military-time-for-midnight-00-to-a-value