Displaying Full DateTime when sorting by hour - sql

I am using microsoft sql server. I am trying to sort my results by the full time.
My raw data looks like this:
TimeStamp TotalOffered
2012-04-16 08:00:00 18
2012-04-16 08:30:00 34
2012-04-16 09:00:00 30
2012-04-16 09:30:00 68
I am sorting by hour blocks for example sum of data during 08:00:00 is 52, sum of data for 09:00:00 is 98, I have it broken down by day.
The Code i have is:
select datepart(hour,[TimeStamp]), SUM([TotalOffered])
from [my table]
group by
datepart(hour,[sus_CallPerformance_TimeStamp]),
dateadd(d, 0, datediff(d, 0, [sus_CallPerformance_TimeStamp]))
I am trying to get the data to show the full TimeStamp instead of just the hour.
Currently the results show as:
8 52
9 98
I would like the results to show as:
2012-04-16 08:00:00 52
2012-04-16 09:00:00 98
Thank You

SELECT DATEADD(HOUR, DATEPART(HOUR, TimeStamp), DATEDIFF(DAY, 0, TimeStamp)) [TimeStamp],
SUM(TotalOffered) [TotalOffered]
FROM [My Table]
GROUP BY DATEADD(HOUR, DATEPART(HOUR, TimeStamp), DATEDIFF(DAY, 0, TimeStamp))
ORDER BY [TimeStamp]

try this:
declare #t table (ts datetime, od int)
insert into #t (ts, od) values ('2012-04-16 08:00:00', 18)
insert into #t (ts, od) values ('2012-04-16 08:30:00', 34)
insert into #t (ts, od) values ('2012-04-16 09:00:00', 30)
insert into #t (ts, od) values ('2012-04-16 09:30:00', 68)
select * from #t
select
dateadd(hour, datepart(hour, ts), cast(floor(cast(ts as real)) as datetime)) as solution,
sum(od)
from #t
group by dateadd(hour, datepart(hour, ts), cast(floor(cast(ts as real)) as datetime))
order by dateadd(hour, datepart(hour, ts), cast(floor(cast(ts as real)) as datetime))

DateTime fields can be cast to floating point values, where the whole number represents the date and the fraction represents the time. If you multipy the date by 24, then the whole number will represent the hour, as follows:
SELECT CAST(FLOOR(CAST(TimeStamp AS FLOAT) * 24)/24.0 AS DateTime) AS Hr, SUM(TotalOffered) AS Total
FROM [my table]
GROUP BY FLOOR(CAST(TimeStamp AS FLOAT) * 24)
ORDER BY FLOOR(CAST(TimeStamp AS FLOAT) * 24)

Related

Rounding time untill in SQL

I have a table with timestamp that I want to round off at 15 min. interval. I can round off using the below Query but it rounds off both 11:58 and 12:02 to 12:00 which is not what I want. I would like to round off timestamp at 15 min. interval which gives me time_untill ie for anything between 11:45 to 11:59 should be rounded off to 12 and anything between 12:00 to 12:14 should be rounded off to 12:15. Please let me know how can I achieve that? Thanks
SELECT transaction_id,
CONVERT(smalldatetime, ROUND(CONVERT(float, CONVERT(datetime, entry_date_time)) * 96.0, 0, 1) /96.0) as transaction_datetime
FROM <table>
You can use datetimefromparts():
select dateadd(minute,
15,
datetimefromparts(year(entry_date_time), month(entry_date_time), day(entry_date_time),
datepart(hour, entry_date_time),
15 * (datepart(minute, entry_date_time) / 15), 0, 0
)
) as roundup15
You could use the DATEADD/DATEDIFF method to truncate date/time values that's been available for a long time.
SELECT transaction_id,
entry_date_time,
DATEADD( MI, DATEDIFF( MI, '2010', entry_date_time)/15*15, '2010') as transaction_datetime
--FROM Sample Data
FROM (SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) transaction_id,
DATEADD( SS, CHECKSUM(NEWID())%10000, CAST( GETDATE() AS smalldatetime)) AS entry_date_time
FROM sys.columns)x;
Something like this...
DECLARE #time TIME(0) = GETDATE();
SELECT
DATEADD(MINUTE,
(((DATEDIFF(MINUTE, '00:00:00', #time) % 60) / 15) * 15),
DATEADD(HOUR, DATEDIFF(HOUR, '00:00:00', #time), '00:00:00')
);

How to calculate business hours/minutes between two dates?

I'm trying to understand how to calculate business hours between 7PM and 7AM.
For Example I have:
Start time: 2018-01-10 19:15:00
End time: 2018-01-11 09:00:00
I expect calculation to return (11:45:00) between 7PM and 7AM.
Your requirements are not very clear, however this should be a good query to start from:
declare #tmp table(StartTime datetime, EndTime datetime)
insert into #tmp values
('2018-07-01 19:35:00', '2018-07-01 21:55:00')
,('2018-08-01 12:35:00', '2018-08-01 21:55:00')
,('2018-08-01 12:35:00', '2018-08-02 05:55:00')
,('2018-08-01 12:35:00', '2018-08-02 07:00:00')
,('2018-08-01 12:35:00', '2018-08-02 07:15:00')
SELECT StartTime
,EndTime
,CASE
WHEN StartTime < dateadd(HOUR, 19, cast(cast(StartTime AS DATE) AS DATETIME))
THEN convert(VARCHAR(5), dateadd(minute, datediff(MINUTE, dateadd(HOUR, 19, cast(cast(StartTime AS DATE) AS DATETIME)),
CASE
WHEN endtime < DATEADD(HOUR, 7, cast(DATEADD(day, 1, cast(StartTime AS DATE)) AS DATETIME))
THEN endtime
ELSE DATEADD(HOUR, 7, cast(DATEADD(day, 1, cast(StartTime AS DATE)) AS DATETIME))
END), 0), 114)
ELSE NULL
END AS Extra_time
FROM #tmp
Results with different test cases:
Note: extra time is capped at 12:00 because you want working hours between 7PM and 7AM
Note 2: extra time is computed only if Start time is before 7 PM because in comments you wrote: "I need only extra hours after 7 PM if Start time before 7 PM"

The correct if statement with and in this situation in SQL Server

I got this data in my database
id shift_no time_in time_out
---------------------------------------
1 Shift 1 06:00:00 14:00:00
2 Shift 2 14:00:00 22:00:00
3 Shift 3 22:00:00 06:00:00
So I got this date:
convert(time(0),dateadd(HOUR, 15, getdate()), 108)
I want to get only the shift that is within the range of this time convert(time(0), dateadd(HOUR, 15, getdate()), 108)
Sorry for an answer, but I'm not able to comment quite yet...this is comment for Tanner's answer.
Can you try splitting the 3rd shift entry:
INSERT INTO #shifts
(
shiftNo,
time_In,
time_Out
)
VALUES
(1, '06:00:00', '14:00:00'),
(2, '14:00:00', '22:00:00'),
(3, '22:00:00', '23:59:59'),
(3, '00:00:00', '06:00:00');
-- the selected time
SELECT CONVERT(TIME(0), DATEADD(HOUR, 15, GETDATE()), 108);
-- filter your shifts
SELECT *
FROM #shifts AS s
WHERE CONVERT(TIME(0), DATEADD(HOUR, -6, GETDATE()), 108)
BETWEEN s.time_In AND s.time_Out;
DROP TABLE #shifts;
You can use BETWEEN with your in and out times like so (note the below is re-runnable):
CREATE TABLE #shifts
(
shiftNo INT,
time_In TIME(0),
time_Out TIME(0)
);
INSERT INTO #shifts
(
shiftNo,
time_In,
time_Out
)
VALUES
(1, '06:00:00', '14:00:00'),
(2, '14:00:00', '22:00:00'),
(3, '22:00:00', '06:00:00');
-- the selected time
DECLARE #selectedTime TIME(0) = CONVERT(TIME(0), DATEADD(HOUR, 12, GETDATE()), 108);
-- modify the selected time if it falls in the shift that crosses midnight
SET #selectedTime = CASE WHEN #selectedTime > '22:00:00' OR #selectedTime < '06:00:00'
THEN '22:01:00' -- modified value
ELSE #selectedTime -- regular value
END;
-- show the time we are working with
SELECT #selectedTime;
-- filter your shifts
SELECT *
FROM #shifts AS s
WHERE #selectedTime
BETWEEN s.time_In AND CASE WHEN s.time_Out = '06:00:00' -- is the out time 6.00
THEN '23:59:59' -- change it to before midnight if so
ELSE s.time_Out -- keep the time as it is
END;
DROP TABLE #shifts;
The CASE statements in the queries work out if the times you are working with #selectedTime is a time that will cross over midnight before s.time_Out they are both adjusted, which allows the last shift to be selected.
There is probably a simpler solution, but this works with the data you have provided.
select
*
from yourtable
where
time_in between getdate() and convert(time(0),dateadd(HOUR, 15, getdate()), 108)
or time_out between getdate() and convert(time(0),dateadd(HOUR, 15, getdate()), 108)

SQL Server: hour and minute average

In SQL Server, I have a start time column on a table such as:
2011-09-18 08:06:36.000
2011-09-19 05:42:16.000
2011-09-20 08:02:26.000
2011-09-21 08:37:24.000
2011-09-22 08:22:20.000
2011-09-23 11:58:27.000
2011-09-24 09:00:48.000
2011-09-25 06:51:34.000
2011-09-26 06:09:05.000
2011-09-27 08:25:26.000
...
My question is, how can I get the average hour and minute? I want to know that what is the average start time for this job. (for example 07:22)
I tried something like this but didn't work:
select CAST(AVG(CAST(DATEPART(HH, START_TIME)AS float)) AS datetime) FROM
Thanks.
declare #T table(StartTime datetime)
insert into #T values
('2011-09-18 08:06:36.000'),
('2011-09-19 05:42:16.000'),
('2011-09-20 08:02:26.000'),
('2011-09-21 08:37:24.000'),
('2011-09-22 08:22:20.000'),
('2011-09-23 11:58:27.000'),
('2011-09-24 09:00:48.000'),
('2011-09-25 06:51:34.000'),
('2011-09-26 06:09:05.000'),
('2011-09-27 08:25:26.000')
;with C(Sec) as
(
select dateadd(second, avg(datediff(second, dateadd(day, datediff(day, 0, StartTime), 0), StartTime)), 0)
from #T
)
select convert(char(5), dateadd(minute, case when datepart(second, C.Sec) >= 30 then 1 else 0 end, C.Sec), 108)
from C
-----
08:08
Try this :
select CAST((SUM(DATEPART(HH, START_TIME) * 60 + DATEPART(MI, START_TIME))/COUNT(*))/60 AS VARCHAR(10)) + ':' + CAST((SUM(DATEPART(HH, START_TIME) * 60 + DATEPART(MI, START_TIME))/COUNT(*))%60 AS VARCHAR(10))
FROM.....

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