How to get an AVG of date time field which is converted in specific format in SQL Server? - sql-server-2017

I have a table where start and end date is available which are in datetime format.
I have two requirements.
Get the difference in hh:mm:ss format.
Get the AVG of that time.
I am able to achieve first requirement but not sure how to get AVG after that. Do I need to cast on the statement where I am getting hh:mm:ss?
Query:
DECLARE #StartDate DATETIME, #EndDate DATETIME, #StartDate2 DATETIME, #EndDate2 DATETIME;
SET #StartDate = '2018-07-17 10:56:06.003';
SET #EndDate = '2018-07-17 10:57:15.967';
SET #StartDate2 = '2018-06-06 15:57:47.823';
SET #EndDate2 = '2018-06-06 16:01:28.707';
SELECT #StartDate AS StartDate,
#EndDate AS EndDate,
CONVERT(VARCHAR(5), DATEDIFF(s, #StartDate, #EndDate) / 3600)+':'+CONVERT(VARCHAR(5), DATEDIFF(s, #StartDate, #EndDate) % 3600 / 60)+':'+CONVERT(VARCHAR(5), (DATEDIFF(s, #StartDate, #EndDate) % 60)) AS [hh:mm:ss],
0 as placeholder
UNION
SELECT #StartDate2 AS StartDate2,
#EndDate2 AS EndDate2,
CONVERT(VARCHAR(5), DATEDIFF(s, #StartDate2, #EndDate2) / 3600)+':'+CONVERT(VARCHAR(5), DATEDIFF(s, #StartDate2, #EndDate2) % 3600 / 60)+':'+CONVERT(VARCHAR(5), (DATEDIFF(s, #StartDate2, #EndDate2) % 60)) AS [hh:mm:ss],
0 as placeholder;
Result:
StartDate EndDate hh:mm:ss placeholder
----------------------- ----------------------- ----------------- -----------
2018-06-06 15:57:47.823 2018-06-06 16:01:28.707 0:3:41 0
2018-07-17 10:56:06.003 2018-07-17 10:57:15.967 0:1:9 0
Here, my expected result in placeholder would be average of 3:41 and 1:9.

Related

Is there an efficient way to break a date range into hours per day?

In SQL Server I am attempting to break a date range into hours per day and have the following bit of code which is OK for a short time frame, but rather inefficient for longer periods of time. Could anyone suggest a more efficient approach?
DECLARE #StartDate datetime = '2015-01-27 07:32:35.000',
#EndDate datetime = '2015-04-29 14:39:35.000',
#TempDate datetime = '';
SET #TempDate = #StartDate;
DECLARE #dateTimeTable TABLE (dt datetime, minCol INT);
WHILE #TempDate < #EndDate
BEGIN
INSERT INTO #dateTimeTable VALUES (CONVERT(date,#TempDate), 1)
SET #TempDate = DATEADD(minute,1,#TempDate)
END
Select dt,
FORMAT(SUM(minCol) / 60.0,'F') as Hours
from #dateTimeTable
GROUP BY dt
Thanks,
Carl
The best way would be to use recursive cte :
DECLARE #StartDate datetime = '2015-01-27 07:32:35.000',
#EndDate datetime = '2015-04-29 14:39:35.000';
WITH cte AS (
SELECT CAST(#StartDate AS DATE) startdate,DATEDIFF(minute, #StartDate, DATEADD(DAY, 1, CAST(#StartDate AS DATE) ) ) / 60.0 hours
UNION ALL
SELECT DATEADD(DAY,1, startdate), DATEDIFF(minute, DATEADD(DAY,1, startdate), CASE WHEN DATEADD(DAY,2, startdate) > #EndDate
THEN #enddate ELSE DATEADD(DAY,2, startdate) END) / 60.0
FROM cte
WHERE startdate <> CAST(#EndDate AS DATE)
)
SELECT * FROM cte
db<>fiddle here

How to calculate difference between two dates in seconds during business hours for business days SQL Server?

I like to get the difference in seconds between two working days in SQL Server. We have date table contains IsWorkingDay flag, if the end date is null then it should default to getdate(). The workday starts at 8 am and finishes at 4:30 pm.
I have the following query, need help in else part.
#StartDate and #EndDate will not always be on workdays. If #StartDate is on any weekend or Holiday, it should roll up to Next working day at 8:00 am. If #EndDate is on any weekend or Holiday, it should roll up to last working day at 4:30 pm.
CREATE FUNCTION TimeDiffInSeconds
(
#Startdate DATETIME
,#EndDate DATETIME
)
RETURNS INT
AS
BEGIN
DECLARE #WorkSeconds INT = 0;
DECLARE #Reverse BIT;
DECLARE #StartHour FLOAT = 8
DECLARE #EndHour FLOAT = 16.50
IF #Startdate > #EndDate
BEGIN
DECLARE #TempDate DATETIME = #Startdate;
SET #Startdate = #EndDate;
SET #EndDate = #TempDate;
SET #Reverse = 1;
END;
ELSE
SET #Reverse = 0;
IF DATEPART(HH, #StartDate) < #StartHour
SET #StartDate = DATEADD(HOUR, #StartHour, DATEDIFF(DAY, 0, #StartDate));
IF DATEPART(HH, #StartDate) >= #EndHour + 1
SET #StartDate = DATEADD(HOUR, #StartHour + 24, DATEDIFF(DAY, 0, #StartDate));
IF DATEPART(HH, #EndDate) >= #EndHour + 1
SET #EndDate = DATEADD(HOUR, #EndHour, DATEDIFF(DAY, 0, #EndDate));
IF DATEPART(HH, #EndDate) < #StartHour
SET #EndDate = DATEADD(HOUR, #EndHour - 24, DATEDIFF(DAY, 0, #EndDate));
IF #Startdate > #EndDate
RETURN 0;
IF DATEDIFF(DAY, #StartDate, #EndDate) <= 0
BEGIN
IF #Startdate <> (SELECT date_id FROM Final.Date WHERE IsWorkingDay = 0)
SET #WorkSeconds = DATEDIFF(ss, #StartDate, #EndDate); -- Calculate difference
ELSE RETURN 0;
END;
ELSE
--need help
RETURN #WorkSeconds;
END
It can be calculated in a simple way.
If your two parameters are already working days then you can just return their difference in seconds, minus 15.5 hours (16:30 to 08:00) for every day difference (every time the midnight boundary is crossed), minus 8,5 hours (8:00 to 16:30) for every not working day between your two dates.
PS: I have updated the answer, so we now first check if #StartDate and #EndDate are correct working datetimes, and if not then we move them to the correct ones. After that you can apply the previously described calculation for the working time in seconds.
CREATE FUNCTION TimeDiffInSeconds
(
#Startdate datetime,
#EndDate datetime
)
RETURNS INT
AS
BEGIN
set #EndDate = coalesce(#EndDate, getdate());
-- We check that #StartDate is a working datetime, and if not we set it to the next one
if convert(time, #StartDate) < convert(time, '08:00')
begin
set #StartDate = convert(datetime, convert(date, #StartDate)) +
convert(datetime, '08:00')
end
if convert(time, #StartDate) > convert(time, '16:30') or
(select IsWorkingDay
from Final.Date
where date_id = convert(date, #StartDate)) = 0
begin
select top 1 #StartDate = convert(datetime, date_id) +
convert(datetime, '08:00')
from Final.Date
where date_id > #StartDate and IsWorkingDay = 1
order by date_id
end
-- We check that #EndDate is a working datetime, and if not we set it to the last one
if convert(time, #EndDate) > convert(time, '16:30')
begin
set #EndDate = convert(datetime, convert(date, #EndDate)) +
convert(datetime, '16:30')
end
if convert(time, #EndDate) < convert(time, '08:00') or
(select IsWorkingDay
from Final.Date
where date_id = convert(date, #EndDate)) = 0
begin
select top 1 #EndDate = convert(datetime, date_id) +
convert(datetime, '16:30')
from Final.Date
where date_id < #EndDate and IsWorkingDay = 1
order by date_id desc
end
-- We return the working time difference in seconds between #StartDate and #EndDate
RETURN datediff(second, #StartDate, #EndDate) -
((15.5 * datediff(day, #StartDate, #EndDate) * 60 * 60) -
(8.5 * (select count(*)
from Final.Date
where IsWorkingDay = 0 and
(date_id between #StartDate and #EndDate or date_id between #EndDate and #StartDate)
) * 60 * 60));
END
Test online: https://rextester.com/FWR14059

Monthly wise count using date calculation

I have the table named company with columns company name, create date, etc.
I want to get the count of companies created for this month.
I have the stored procedure for weekly wise count
CREATE PROCEDURE [dbo].[pr_NewCmpCount]
#StartDate DATETIME = NULL --'20130508'
, #EndDate DATETIME = NULL --'20130515'
AS
BEGIN
DECLARE #DateDiff INT
, #MainDate DATETIME
IF #StartDate IS NULL AND #EndDate IS NULL
BEGIN
IF (DATEPART(dw,GETDATE()) > 3)
SET #DateDiff = 0
ELSE
SET #DateDiff = 6
SET #MainDate = DATEADD (MINUTE, -30, DATEADD (HOUR, -5, DATEADD(wk, DATEDIFF(wk,#DateDiff,GETDATE()), 0)))
SELECT #StartDate = DATEADD (MINUTE, -30, DATEADD (HOUR, -5, DATEADD(wk, DATEDIFF(wk,0,#MainDate), -5)))
SELECT #EndDate = DATEADD (MINUTE, -30, DATEADD (HOUR, -5, DATEADD(wk, DATEDIFF(wk,0,#MainDate), 2)))
SELECT CONVERT (VARCHAR, Count(*)) AS [Count]
, CONVERT (DATE, DATEADD (DD, 1, #StartDate)) AS [StartDate]
, CONVERT (DATE, #EndDate) AS [EndDate]
FROM
Company WITH(NOLOCK)
WHERE CreateDate >= #StartDate
AND CreateDate < #EndDate
END
ELSE
IF ((CONVERT (DATE, #StartDate) < CONVERT (DATE, #EndDate)) AND (CONVERT (DATE, #EndDate) < CONVERT (DATE, GETDATE())))
BEGIN
SET #StartDate = CONVERT (DATE, #StartDate)
SET #EndDate = CONVERT (DATE, #EndDate)
SELECT #StartDate = DATEADD (MINUTE, -30, DATEADD (HOUR, -5, #StartDate))
SELECT #EndDate = DATEADD (MINUTE, 30, DATEADD (HOUR, 18, #EndDate))
SELECT CONVERT (VARCHAR, Count(*)) AS [Count]
, CONVERT (DATE, DATEADD (DD, 1, #StartDate)) AS [StartDate]
, CONVERT (DATE, #EndDate) AS [EndDate]
FROM
Company WITH(NOLOCK)
WHERE CreateDate >= #StartDate
AND CreateDate < #EndDate
END
ELSE
SELECT 'Please Run After Tuesday of Every Week or Given the Valid Date' [Count]
, CONVERT (DATE, #StartDate) AS [StartDate]
, CONVERT (DATE, #EndDate) AS [EndDate]
END
Output for this stored procedure is
Count Startdate EndDate
10 2016-03-13 2016-03-22
Expected output
Count Startdate EndDate
20 2016-02-01 2016-02-29
Where do I need to modify in my stored procedure to get monthly wise count?
Something like this:
DECLARE #StartDt Date
DECLARE #EndDt date
SELECT #StartDt,#EndDt,Count(*) AS TotalCompanies FROM company
WHERE [create date] BETWEEN #StartDt AND #EndDt
I skipped the stored procedure formatting for simplicity.

Difference between two dates in exact number of hours in SQL

I would like to calculate the exact hours difference between two datetime variables. The hours difference should be exact like this:
1.5
2
6.25
Anybody please help out..Thanks in advance...
You could use DATEDIFF to find the difference in minutes and convert that into hours:
select datediff(mi, startdate, enddate)
Assuming 1.5 means 1 hour and 30 minutes you could simply divide the result by 60:
select datediff(mi, startdate, enddate) / 60.0
Keep it simple:
declare #date1 datetime
declare #date2 datetime
select #date1 = GETDATE();
select #date2 = '2013-02-02 14:05'
select DATEDIFF(hh, #date2, #date1)
Results
-----------
71
(1 row(s) affected)
it will help you....
Declare #Date1 dateTime
Declare #Date2 dateTime
Set #Date1 = '22:30:00'
Set #Date2 = '00:00:00'
Select Cast((#Date1 - #Date2) as Float) * 24.0
To get Exact Time Difference in HH:MM try the below code in MS-SQL
Declare #InTime datetime='2017-11-27 10:00:00',
#OutTime datetime='2017-11-27 11:15:00'
SELECT CONVERT(varchar(5),DATEADD(minute,DATEDIFF(minute,#InTime,#OutTime),0), 114)
-----------
Result
01:15
Please try:
declare #dt1 datetime, #dt2 datetime, #Seconds int
select #dt1='2013-02-05 14:05:55.113', #dt2 =getdate()
set #Seconds=datediff(second, #dt1, #dt2)
declare #Hour nvarchar(50)
declare #Min nvarchar(50)
declare #MinTemp int
if #Seconds >0
begin
set #Hour=cast((#Seconds / 3600) as nvarchar(20)) +' Hrs '
set #MinTemp= (#Seconds % 3600) / 60
set #Min=cast(#MinTemp as nvarchar(20))
if #MinTemp<10
select #Hour+'0'+#Min +' Min'
else
select #Hour+#Min +' Min'
end
else
select '00 Hrs 00 Min'

Performing date/time subtraction in SQL Server

I have four columns in a table:
date entered, time entered, date completed, time completed
I would like to know the difference between date/time ENTERED and date/time COMPLETED
For example
date entered = 1/1/2001
time entered = 10:00
time completed = 1/2/2001
time completed = 11:00
The difference is 25 hours.
How can I perform this computation with a select statement?
I tried this:
DATEDIFF(hh,dateadd(hh,[Time Entered],[Date Entered]),dateadd(hh,[Time Completed],[Date Completed]) ) AS [Hours]
and got the following error:
Msg 8116, Level 16, State 1, Line 2
Argument data type time is invalid for argument 2 of dateadd function.
Declare #dateentered date = '20010101'
Declare #timeentered time = '10:00'
Declare #datecompleted date = '20010102'
Declare #timecompleted time = '11:00'
select datediff(hh, #dateentered + cast(#timeentered as datetime),
#datecompleted + cast(#timecompleted as datetime))
So, in terms of your tables' columns:
select datediff(hh, [date entered] + cast([time entered] as datetime),
[date completed] + cast([time completed] as datetime)) as [Hours]
select datediff(hour,'1/1/2001 10:00','1/2/2001 11:00')
Try
select DateDiff(ss, [Date Entered] + convert(datetime, [Time Entered]),
[Date Completed] + convert(datetime, [Time Completed]))
from myTable
to get the result in seconds.
Here's a standalone example:
declare #dateentered date = '1/1/2001'
declare #timeentered time = '10:00'
declare #datecompleted date = '1/2/2001'
declare #timecompleted time = '11:00'
select DateDiff(ss,
#dateentered + convert(datetime, #timeentered),
#datecompleted + convert(datetime, #timecompleted))
And of course you can specify different dateparts as specified for DATEDIFF.
Use DateDiff
DECLARE #StartDate DATETIME
Declare #EndDate DATETIME
declare #startime datetime
declare #endime datetime
SET #StartDate = '2001-01-01'
set #startime = '10:00'
SET #EndDate = '2001-01-02'
set #endime = '11:00'
set #StartDate = #StartDate + #startime
set #EndDate = #EndDate + #endime
--To get only Hours
SELECT DATEDIFF(hh, #StartDate,#EndDate ) AS [Hours];