How to break datetime in 15 minute interval in sql sever 2014 - sql

I have split the below query in 15 minute interval on the basis of Start datetime but this query is not providing the exact result set
as i am expecting.
Below is the example of query i want to execute.
select Date_Stamp,
Case when substring(convert(char(8),starttime,114), 1, 8) between '12:00:01 AM'and '12:15:00 AM' then '0015'
when substring(convert(char(8),starttime,114), 1, 8) between '12:15:01 AM'and '12:30:00 AM' then '0030'
when substring(convert(char(8),starttime,114), 1, 8) between '12:30:01 AM'and '12:45:00 AM' then '0045'
when substring(convert(char(8),starttime,114), 1, 8) between '12:45:01 AM'and '01:00:00 AM' then '0100'
and i want the result as
Date Need result set
12:01 AM '0015'
'12:15:01 '0030'
'12:30:01 '0045'
'12:45:01 '0100'
'01:00:01 '0115'
'01:15:01 '0130'
'01:30:01 '0145'
'01:45:01 '0200'
'02:00:01 '0215'
'02:15:01 '0230'
'02:30:01 '0245'
3:00:00 ' '0015'
'12:30:00 '0030'
'12:45:00 '0045'
'01:00:00 '0100'
'01:15:00 '0115'
'01:30:00 '0130'
'01:45:00 '0145'
'02:00:00 '0200'
'02:15:00 '0215'
'02:30:00 '0230'
'02:45:00 '0245'

Just change #starttime with your column name
DECLARE #starttime datetime = getdate()
SELECT CONCAT(CASE WHEN DATEPART(HH, #starttime) <= 9
THEN '00'+ CAST(DATEPART(HH, #starttime) AS VARCHAR(2))
ELSE '0'+CAST(DATEPART(HH, #STARTTIME) AS VARCHAR(2))
END,
CASE WHEN DATEPART(MINUTE, #STARTTIME) BETWEEN 1 AND 15
THEN 15
WHEN DATEPART(MINUTE, #STARTTIME) BETWEEN 16 AND 30
THEN 30
WHEN DATEPART(MINUTE, #STARTTIME) BETWEEN 31 AND 45
THEN 45
WHEN DATEPART(MINUTE, #STARTTIME) BETWEEN 46 AND 59 OR DATEPART(MINUTE, #STARTTIME) = 0
THEN 00
END)

You can use this date generator:
DEMO
DECLARE #Break INT = 15
;WITH Numbers (n) as
(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL))-1
FROM (VALUES (0),(0),(0),(0),(0),(0),(0),(0)) a(n)
CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) b(n)
CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) c(n)
CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) d(n)
)
,Dates as
(
SELECT dt
FROM Numbers
CROSS APPLY
(
VALUES (DATEADD(MINUTE , n, CAST(CAST(GETDATE() AS DATE) AS DATETIME)))
) X(Dt)
WHERE N % #Break = 0
AND CAST(DT AS DATE) = CAST(GETDATE() AS DATE) --Only for today's date
)
SELECT CONVERT(VARCHAR(10),Dt,108) [Time] , REPLACE(CONVERT(VARCHAR(5),ISNULL(Lead(Dt) OVER (ORDER BY Dt) , DATEADD(MINUTE,#Break,Dt)),108), ':','') Grp
FROM Dates

It appears you're using datetime and have only taken the substring of the time. A string cannot be compared to a time, without being casted to the time datatype.
For example:
DECLARE #mytable TABLE (starttime datetime)
INSERT INTO #mytable VALUES ('2018-03-13 00:00:01'), ('2018-03-15 00:00:01')
SELECT * FROM #mytable
select CAST(starttime as time(0)) AS [thetime],
Case when CAST(starttime as time) between '12:00:01 AM'and '12:15:00 AM' then '0015'
when CAST(starttime as time) between '12:15:01 AM'and '12:30:00 AM' then '0030'
when CAST(starttime as time) between '12:30:01 AM'and '12:45:00 AM' then '0045'
when CAST(starttime as time) between '12:45:01 AM'and '01:00:00 AM' then '0100'
END AS [Interval]
FROM #mytable
Produces:
thetime Interval
00:00:01 0015
00:15:01 0030

Related

Error message: Maximum Recursion exhausted even with OPTION( MAXRECURSION 0)

I'm creating a function that will have as input a start date and a number of minutes. The function will add the number of minutes to the start date and it will output an end date, but only considering work hours and excluding weekends and holidays.
You can see part of the function below.
ALTER FUNCTION [dbo].[DataFimPrevisto] (#tempoPrevisto real, #DataIni datetime)
RETURNS datetime
WITH EXECUTE AS CALLER
AS
BEGIN
DECLARE #DataFim datetime;
DECLARE #calculo TABLE( xend datetime, [minutes] int);
WITH
drange (date_start, date_end) AS
(
SELECT
CAST(#DataIni AS DATE) AS date_start,
CAST(DATEADD( YEAR, 1, #DataIni) AS DATE) AS date_end
),
dates0 (adate, date_end) AS
(
SELECT date_start, date_end FROM drange
UNION ALL
SELECT DATEADD(day, 1, adate), date_end FROM dates0 WHERE adate < date_end
),
dates (adate) AS
(
SELECT adate FROM dates0
WHERE DATEPART(dw , adate) NOT IN ('1', '7') AND NOT EXISTS( SELECT 1 FROM BAS_PeriodosExcecoes B WHERE B.Trabalhavel = 0 AND B.DataInicio = adate)
),
hours (hour_start, hour_end) AS
(
SELECT 8.5*60, 12.5*60
UNION
SELECT 13.5*60, 18*60
),
hours_friday (hour_start, hour_end) AS
(
SELECT 8*60, 14*60
),
datehours (xstart, xend) AS
(
SELECT *
FROM
(
SELECT
DATEADD(minute, hour_start, CAST(adate AS datetime)) xstart,
DATEADD(minute, hour_end , CAST(adate AS datetime)) xend
FROM dates AS d, hours AS h
WHERE DATEPART(dw , adate) <> '6'
UNION
SELECT T2.xstart, T2.xend
FROM
(
SELECT *, ROW_NUMBER() OVER(PARTITION BY T.xstart ORDER BY T.xend ASC) AS rank
FROM
(
SELECT
#DataIni xstart,
DATEADD(minute, hour_end, CAST(adate AS datetime)) xend
FROM dates AS d, hours AS h
WHERE adate = CAST( #DataIni AS DATE) AND DATEADD(minute, hour_end, CAST(adate AS datetime)) > #DataIni AND DATEPART(dw , adate) <> '6'
) T
) T2
WHERE T2.rank = 1
UNION
SELECT
DATEADD(minute, hour_start, CAST(adate AS datetime)) xstart,
DATEADD(minute, hour_end , CAST(adate AS datetime)) xend
FROM dates AS d, hours_friday AS h
WHERE DATEPART(dw , adate) = '6'
UNION
SELECT T2.xstart, T2.xend
FROM
(
SELECT *, ROW_NUMBER() OVER(PARTITION BY T.xstart ORDER BY T.xend ASC) AS rank
FROM
(
SELECT
#DataIni xstart,
DATEADD(minute, hour_end, CAST(adate AS datetime)) xend
FROM dates AS d, hours_friday AS h
WHERE adate = CAST( #DataIni AS DATE) AND DATEADD(minute, hour_end, CAST(adate AS datetime)) > #DataIni AND DATEPART(dw , adate) = '6'
) T
) T2
WHERE T2.rank = 1
) T3 WHERE T3.xstart >= #DataIni
),
cumulative (xend, [minutes]) AS
(
SELECT t.xend, SUM(DATEDIFF(MINUTE, xstart, xend)) OVER (ORDER BY xstart) AS [minutes]
FROM datehours AS t
)
INSERT INTO #calculo
SELECT TOP 1 xend, [minutes]
FROM cumulative
WHERE [minutes] >= #tempoPrevisto
ORDER BY cumulative.xend ASC;
SET #DataFim = (SELECT DATEADD( MINUTE, #tempoPrevisto - MAX([minutes]), MAX( [xend])) FROM #calculo);
RETURN(#DataFim);
END;
When I execute this function with
SELECT dbo.DataFimPrevisto( 21240, DATETIMEFROMPARTS( 2023, 1, 25, 6, 0, 0, 0)) OPTION(MAXRECURSION 0);
SSMS returns the error message
The maximum recursion 100 has been exhausted before statement completion
Even tho I'm using OPTION(MAXRECURSION 0).

How to get records in specific time range when the time range is between two days

I'm trying to query a specific range of time:
i.e. 1/1/2021 - 1/31/2021
between 5:55AM - 5:00AM (next day) for all days in above date
You need to extract time portion from your timestamps (datetime type for T-SQL) and filter by them in addition to dates filter.
db<>fiddle here
declare
#dt_from datetime
, #dt_to datetime
, #tm_from time
, #tm_to time
, #dt datetime
;
select
#dt = convert(datetime, '2021-02-10 11:48:36', 120)
, #dt_from = convert(date, '2021-02-01', 23)
, #dt_to = convert(date, '2021-02-28', 23)
, #tm_from = convert(time, '05:55:00', 120)
, #tm_to = convert(time, '05:00:00', 120)
;
with a as (
select #dt as dt union all
select dateadd(hour, 20, #dt) union all
select dateadd(hour, -15, #dt) union all
select dateadd(hour, -6, #dt) union all
select dateadd(day, -30, #dt) union all
select convert(datetime, '2021-02-01 00:01:02', 120) union all
select convert(datetime, '2021-02-28 20:01:02', 120)
)
select *
from dt
/*Restrict dates*/
where dt >= #dt_from
and dt < dateadd(day, 1, #dt_to)
and (
/*Exclude time intervals between 05:00 and 05:55*/
cast(dt as time) <= #tm_to
or cast(dt as time) >= #tm_from
)
Or if you need only the cases when entire time frame falls into your dates (e.g. exclude times from 00:00 till 05:00 for start date and from 05:55 till 23:59:59 of end date):
select *
from dt
where dt between #dt_from and #dt_to
and (
/*Exclude time intervals between 05:00 and 05:55*/
cast(dt as time) <= #tm_to
or cast(dt as time) >= #tm_from
)
/*Exclude time intervals at boundary dates*/
and not(
(cast(dt as date) = #dt_from and cast(dt as time) <= #tm_to)
or (cast(dt as date) = #dt_to and cast(dt as time) >= #tm_from)
)

Count how many times a time occurs within a date range

I could not think of a good way to phrase this question to search properly if its already been asked.
I'm looking for a way in SQL 2008 R2 to count how many times 6pm occurs between two datetime values.
For example between '2017-04-17 19:00:00' and '2017-04-19 17:00:00' 6pm only occurs once even though the times span 3 different days.
Between '2017-04-17 18:00:00' and '2017-04-19 18:00:00' it occurs 3 times whilst also spanning 3 days.
Heres a really silly made up expression of what I want for illustration.
timecount(hh, 6, min(datefield), max(datefield))
Thank you
A simple query to count:
DECLARE #StartDate datetime = '2017-04-17 18:00:00'
DECLARE #EndDate datetime = '2017-04-19 18:00:00'
SELECT
CASE
WHEN CAST(#StartDate AS time) <= '18:00' AND CAST(#EndDate AS time) >= '18:00'
THEN datediff(day, #StartDate, #EndDate) + 1
WHEN CAST(#StartDate AS time) <= '18:00' AND CAST(#EndDate AS time) < '18:00'
THEN datediff(day, #StartDate, #EndDate)
WHEN CAST(#StartDate AS time) > '18:00' AND CAST(#EndDate AS time) >= '18:00'
THEN datediff(day, #StartDate, #EndDate)
ELSE datediff(day, #StartDate, #EndDate) - 1
END AS TotalCount
This will give you each hour and the number of occurences:
select datepart(hh, DateColumn) as TheHours, count(*) as occurs
from MyTable
where DateColumn between #SomeDate and #SomeOtherDate
group by datepart(hh, DateColumn)
Or just for 6pm:
select count(*)
from MyTable
where datepart(hh, DateColumn) = 18
and DateColumn between #SomeDate and #SomeOtherDate
DECLARE
#Time time = '18:00',
#From datetime = '2017-04-17 18:00:00',
#To datetime = '2017-04-19 18:00:00'
SELECT
CASE
-- Same date
WHEN DATEDIFF(DAY, #From, #To) = 0 THEN
CASE WHEN CAST(CAST(#From AS date) AS datetime) + #Time BETWEEN #From AND #To THEN 1 ELSE 0 END
-- Not same date
WHEN #From <= #To THEN
CASE WHEN #Time >= CAST(#From AS time) THEN 1 ELSE 0 END
+ DATEDIFF(DAY, #From, #To) - 1
+ CASE WHEN #Time <= CAST(#To AS time) THEN 1 ELSE 0 END
-- Invalid range
ELSE 0
END AS CountOfTime
Try below formula I have tried with different scenario and it works, let me know if I miss any scenario and not work as per your requirement.
DECLARE #firstDate Datetime='17-Apr-2017 17:00:00'
DECLARE #secondDate Datetime='17-Apr-2017 18:59:00'
SELECT
CASE WHEN DATEDIFF(day,#firstDate,#secondDate)=0
THEN IIF(CAST(#firstDate AS TIME) <='18:00' AND DATEPART(hh,#secondDate) >=18,1,0)
ELSE
CASE WHEN
(
CAST(#firstDate AS TIME) <='18:00' AND CAST(#secondDate AS TIME) <'18:00'
OR
CAST(#firstDate AS TIME) >'18:00' AND CAST(#secondDate AS TIME) >='18:00'
)
THEN DATEDIFF(day,#firstDate,#secondDate)
WHEN CAST(#firstDate AS TIME) <='18:00' AND CAST(#secondDate AS TIME) >='18:00' THEN DATEDIFF(day,#firstDate,#secondDate)+1
ELSE DATEDIFF(day,#firstDate,#secondDate)-1
END
END AS TotalCount
Try the below script, using CTE
DECLARE #F_DATE AS DATETIME = '2017-04-17 19:00:00'
,#T_DATE AS DATETIME = '2017-04-19 17:00:00'
;WITH CTE
AS (
SELECT (CASE WHEN DATEPART(HH,#F_DATE) <= 18
THEN #F_DATE
ELSE (CASE WHEN DATEDIFF(DAY,#F_DATE,#T_DATE) > 0
THEN DATEADD(DAY,1,#F_DATE) END)
END) AS CDATE
UNION ALL
SELECT DATEADD(DAY,1,CDATE)
FROM CTE
WHERE DATEADD(DAY,1,CDATE) <= #T_DATE
)
SELECT COUNT(CDATE) DATE_COUNT
FROM CTE
OPTION ( MAXRECURSION 0 )
Here's the count of every 6pm between two datetime:
DECLARE #StartDate datetime
DECLARE #EndDate datetime
set #StartDate = '2017-04-17 19:00:00'
set #EndDate = '2017-04-19 17:00:00'
;WITH cte1 (S) AS (
SELECT 1 FROM (VALUES (1), (1), (1), (1), (1), (1), (1), (1), (1), (1)) n (S)
),
cte2 (S) AS (SELECT 1 FROM cte1 AS cte1 CROSS JOIN cte1 AS cte2),
cte3 (S) AS (SELECT 1 FROM cte1 AS cte1 CROSS JOIN cte2 AS cte2)
select count(datepart(hour,result)) as count from
(SELECT TOP (DATEDIFF(hour, #StartDate, #EndDate) + 1)
result = DATEADD(hour, ROW_NUMBER() OVER(ORDER BY S) - 1, #StartDate)
FROM cte3) as res where datepart(hour,result) = 18
Here's the detailed view of 6pm between two datetime:
DECLARE #StartDate datetime
DECLARE #EndDate datetime
set #StartDate = '2017-04-17 19:00:00'
set #EndDate = '2017-04-19 17:00:00'
;WITH cte1 (S) AS (
SELECT 1 FROM (VALUES (1), (1), (1), (1), (1), (1), (1), (1), (1), (1)) n (S)
),
cte2 (S) AS (SELECT 1 FROM cte1 AS cte1 CROSS JOIN cte1 AS cte2),
cte3 (S) AS (SELECT 1 FROM cte1 AS cte1 CROSS JOIN cte2 AS cte2)
select result,datepart(hour,result) from
(SELECT TOP (DATEDIFF(hour, #StartDate, #EndDate) + 1)
result = DATEADD(hour, ROW_NUMBER() OVER(ORDER BY S) - 1, #StartDate)
FROM cte3) as res where datepart(hour,result) = 18
Here gives the count between any date ranges
declare #time datetime='06:00:00'
declare #startDate datetime='04/20/2017 05:00:00'
declare #enddate datetime='04/21/2017 05:00:00'
SELECT
case
WHEN datediff(ss,#time, convert(time(0),#startDate)) <=0 and datediff(ss,#time, convert(time(0),#enddate)) >=0
THEN datediff(dd,#startDate,#enddate) +1
WHEN (datediff(ss,#time, convert(time(0),#startDate)) <=0 and
datediff(ss,#time, convert(time(0),#enddate)) <=0
OR
datediff(ss,#time, convert(time(0),#startDate))> 0 and
datediff(ss,#time, convert(time(0),#enddate)) >0
OR
datediff(ss,#time, convert(time(0),#startDate))> 0 and datediff(ss,#time, convert(time(0),#enddate)) <=0
)
then datediff(dd,#startDate,#enddate)
ELSE
datediff(dd,#startDate,#enddate)-1
END

Split hours between dates based on date range

Split hours spanning between multiple days
I have data like this.
StartDate EndDate
2015-10-05 20:00:00.000 2015-10-06 12:00:00.000
I need this data to be split by date like
2015-10-05 240 (4 hours)
2015-10-06 720 (12 hours)
I can get the first start date split like this
select (StartDate as date) as StartDate,
DATEDIFF(minute, StartDate, dateadd(day, 1, Cast(StartDate as date))) as diff
from t
which gives me
2015-10-05 240
And get the end date's data like
select
Cast(EndDate as date) as StartDate,
DATEDIFF(minute, Cast(EndDate as date), EndDate) as diff
from t
2015-10-06 720
But I am not sure how to do it all in one query. Besides, the time diff betweens start and end can be more than one day diff like this
StartDate EndDate
2015-10-05 20:00:00.000 2015-10-08 12:00:00.000
for which I need
2015-10-05 240
2015-10-06 1440
2015-10-07 1440
2015-10-06 720
Thanks for looking
This should cover when start and end are on the same date and no limit on days
EDIT: fixed issue with incorrect calculation for the end date
declare #StartDate datetime, #EndDate datetime
set #StartDate = '2015-10-05 20:00'
set #EndDate = '2015-10-05 21:00'
;WITH cte AS
(
SELECT cast(#StartDAte as date) StartDate,
cast(dateadd(day, 1, #StartDAte) as date) EndDate
UNION ALL
SELECT DATEADD(day, 1, StartDate) StartDate,
DATEADD(day, 2, StartDate) EndOfDate
FROM cte
WHERE DATEADD(day, 1, StartDate) <= #EndDate
)
select StartDate,
case
when cast(#StartDate as date) = cast(#EndDate as date) then datediff(minute, #StartDate, #EndDate )
when StartDate = cast(#StartDate as date) then datediff(minute, #StartDate, cast(EndDate as datetime))
when StartDate = cast(#EndDate as date) then datediff(minute, cast(StartDate as datetime), #EndDate)
else 1440 end
from cte
Try it like this:
Remark: If the full intervall can be more than 10 days just add some more values to the tally table. Attention: This solution does not yet cover the situation, when start and end is on the same day...
DECLARE #d1 DATETIME={ts'2015-10-05 08:00:00'};
DECLARE #d2 DATETIME={ts'2015-10-07 12:00:00'};
WITH SomePreCalculations AS
(
SELECT #d1 AS D1
,#d2 AS D2
,CAST(#d1 AS DATE) AS StartDate
,DATEADD(DAY,1,CAST(#d1 AS DATE)) AS FirstMidnight
,CAST(#d2 AS DATE) AS LastMidnight
)
,Differences AS
(
SELECT *
,DATEDIFF(MINUTE,D1,FirstMidnight) AS TilMidnight
,DATEDIFF(MINUTE,LastMidnight,D2) AS FromMidnight
FROM SomePreCalculations
)
,TallyTable AS
(
SELECT RowInx FROM (VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9),(10)) AS x(RowInx)
)
SELECT CAST(Date AS DATE),Minutes FROM
(
SELECT 0 AS Inx, D1 AS Date, TilMidnight AS Minutes
FROM Differences
UNION SELECT RowInx,(SELECT DATEADD(DAY,RowInx,(SELECT StartDate FROM SomePreCalculations))),1440
FROM TallyTable
WHERE DATEADD(DAY,RowInx,(SELECT StartDate FROM SomePreCalculations))<(SELECT LastMidnight FROM SomePreCalculations)
UNION SELECT 99 AS Inx, D2, FromMidnight
FROM Differences
) AS tbl
ORDER BY tbl.Inx

How to display roundof time

Using SQL Server 2005
Table1
ID Intime Outtime
001 00.21.00 00.48.00
002 08.23.00 13.45.00
003 00.34.00 00.18.00
I need to display the time time like 30 minutes or 1 Hours, it should display a roundoff time
Expected Output
ID Intime Outtime
001 00.30.00 01.00.00
002 08.30.00 14.00.00
003 01.00.00 00.30.00
How to make a query for the roundoff time.
You can round the current date to 30 minutes like:
select dateadd(mi, datediff(mi,0,getdate())/30*30, 0)
Explanation: this takes the number of minutes since the 0-date:
datediff(mi,0,getdate())
Then it rounds that to a multiple of 30 by dividing and multiplying by 30:
datediff(mi,0,getdate())/30*30
The result is added back to the 0-date to find the last 30 minute block
dateadd(mi, datediff(mi,0,getdate())/30*30, 0)
This can be adjusted easily for 60 minutes. :)
By checking the range
select ID,
DateAdd(mi, DateDiff(mi, 0, Intime +
case when InMi >= 15 then 30 - InMi else - InMi end), 0) as Intime,
DateAdd(mi, DateDiff(mi, 0, Outtime +
case when OutMi >= 15 then 30 - OutMi else - OutMi end), 0) as Outtime
FROM
(
select ID, Intime, Outtime,
datepart(mi, InTime) % 30 InMi,
datepart(mi, Outtime) % 30 OutMi
from tbl
) X
or by using the classical trick equivalent to Int(x+0.5)..
select ID,
dateadd(mi, ((datediff(mi, 0, Intime)+15)/30)*30, 0) Intime,
dateadd(mi, ((datediff(mi, 0, Outtime)+15)/30)*30, 0) Outtime
from tbl
IF you want to ROUNDUP instead
(you have a value going from 00.34.00 to 01.00.00) Then you need this
select ID,
dateadd(mi, ((datediff(mi, 0, Intime)+29)/30)*30, 0) Intime,
dateadd(mi, ((datediff(mi, 0, Outtime)+29)/30)*30, 0) Outtime
from tbl
Take a look at the DATEDIFF, DATEADD and DATEPART. You should be able to do what you want with that.
http://msdn.microsoft.com/en-us/library/ms189794.aspx
http://msdn.microsoft.com/en-us/library/ms186819.aspx
http://msdn.microsoft.com/en-us/library/ms174420.aspx
Here is kind of a step-by-step routine. I'm sure you can do something shorter and even more efficient. It would also simplify a lot if you used a datetime data type instead of a string.
declare #T table (id char(3), intime char(8), outtime char(8))
insert into #T values ('001', '00.21.00', '00.48.00')
insert into #T values ('002', '08.23.00', '13.45.00')
insert into #T values ('003', '00.34.00', '00.18.00')
;with
cteTime(id, intime, outtime)
as
( -- Convert to datetime
select
id,
cast(replace(intime, '.', ':') as datetime),
cast(replace(outtime, '.', ':') as datetime)
from #T
),
cteMinute(id, intime, outtime)
as
( -- Get the minute part
select
id,
datepart(mi, intime),
datepart(mi, outtime)
from cteTime
),
cteMinuteDiff(id, intime, outtime)
as
( -- Calcualte the desired diff
select
id,
case when intime > 30 then (60 - intime) else (30 - intime) end,
case when outtime > 30 then (60 - outtime) else (30 - outtime) end
from cteMinute
),
cteRoundTime(id, intime, outtime)
as
( -- Get the rounded time
select
cteTime.id,
dateadd(mi, cteMinuteDiff.intime, cteTime.intime),
dateadd(mi, cteMinuteDiff.outtime, cteTime.outtime)
from cteMinuteDiff
inner join cteTime
on cteMinuteDiff.id = cteTime.id
),
cteRoundedTimeParts(id, inHour, inMinute, outHour, outMinute)
as
( -- Split the time into parts
select
id,
cast(datepart(hh, intime) as varchar(2)) as inHour,
cast(datepart(mi, intime) as varchar(2)) as inMinute,
cast(datepart(hh, outtime) as varchar(2)) as outHour,
cast(datepart(mi, outtime) as varchar(2)) as outMinute
from cteRoundTime
),
cteRoundedTime(id, intime, outtime)
as
( -- Build the time string representation
select
id,
right('00'+inHour, 2)+'.'+right('00'+inMinute, 2)+'.00',
right('00'+outHour, 2)+'.'+right('00'+outMinute, 2)+'.00'
from cteRoundedTimeParts
)
select *
from cteRoundedTime