calculate avg time in MS SQL - sql-server

i have a table with datetime, i need to find the avg of the time. i tried CASE statement but it gave me an error Operand data type time is invalid for avg operator.
select * from datestime
dates
2015-11-23 15:05:40.923
2015-11-23 15:05:43.610
2015-11-23 15:05:45.790
2015-11-23 15:05:48.293
first I split the colum into two column date and time
"select convert(date,dates,104) as date,convert(time,dates,108) as time from datestime"
then use CASE To calculate the avg of time.
;with avgtime as(
select convert(date,dates,104) as date,convert(time,dates,108) as time from datestime)
select avg(time) from avgtime
please help me to find the avg time

You can get the midpoint between the start/end date in the range by doing this:
declare #start datetime = '2015-12-01T10:00:00'
declare #finish datetime = '2015-12-01T11:00:00'
print dateadd( second, ( datediff( second, #start, #finish ) / 2 ), #start )

Related

Getting individual dates from a date range using T-SQL

I have been asked to create two datasets showing 7 days of dates from a two date range.
Example: I have a date range of StartDate = 2022-12-12 and EndDate = 2022-12-25. I need a query to display the individual dates in between these two dates. I was told to use DATEADD, but cannot for the life figure this out.
Any help would be be helpful, thank you.
SELECT DATEADD(DAY, 7, StartDate) AS WeekOne
I was expecting something like this:
2022-12-12
2022-12-13
2022-12-14
2022-12-15
2022-12-16
2022-12-17
2022-12-18
DECLARE #InStartDate DATE='2022-12-12';
DECLARE #InStopDate DATE='2022-12-25';
WITH GEN AS
(
SELECT #InStartDate AS Start_dated
UNION ALL
SELECT DATEADD(DD,1,G.Start_dated)
FROM GEN AS G
WHERE G.Start_dated< #InStopDate
)
SELECT G.*
FROM GEN AS G
You can use something like this
You need to start by generating a numbers table. It needs enough rows to handle each day between your start and end dates. Something like this:
with Numbers as (
select 0 as n
union all
select n + 1
from Numbers
where n < 365
)
select n
from Numbers
option(maxrecursion 0);
Given the example range, I felt like 365 days (one year) was adequate, but it's easy to tweak that range (as we'll see).
Once you have the Numbers table, you can use DateAdd() to add that amount to the start date:
DECLARE #StartDate date = '20221212';
with Numbers as (
select 0 as n
union all
select n + 1
from Numbers
where n < 365
)
select DATEADD(day, n, #StartDate)
from Numbers
option(maxrecursion 0)
From here it's a simple matter to use the EndDate in a WHERE clause to limit the total rows:
DECLARE #StartDate date = '20221212';
DECLARE #EndDate date = '20221231';
with Numbers as (
select 0 as n
union all
select n + 1
from Numbers
where n < DATEDIFF(day, #StartDate, #EndDate)
)
select DATEADD(day, n, #StartDate)
from Numbers
option(maxrecursion 0)
For SQL Server 2022 and later you can use Generate_Series:
declare #StartDate as Date = '20221212', #EndDate as Date = '20221225';
select DateAdd( day, Value, #StartDate ) as TargetDate
from Generate_Series( 0, DateDiff( day, #StartDate, #EndDate ) );
dbfiddle.

SELECT Average Count of IIS method calls per second

I'm trying to find out the average count of IIS calls per second (GET, POST, PUT, etc) in a time span of one week
Here's an example of a SELECT I'd use to get total counts in a week:
SELECT Method, COUNT(*)
AS TotalCalls
FROM IISLog
WHERE dDate
BETWEEN '2018-05-10'
AND '2018-05-17'
GROUP BY Method
How can I granularise this SELECT to get an average count of Method calls per second in this date range?
Expected output for calls per second:
Method CallsPerSecond
Get 15
Put 10
Post 14
Delete 12
The number counts are just example estimates
Just divide by the amount of seconds that compose your filter ranges.
DECLARE #StartDate DATETIME = '2018-05-10'
DECLARE #EndDate DATETIME = '2018-05-17'
SELECT
Method,
CallsPerSecond = COUNT(*) / NULLIF(DATEDIFF(SECOND, #StartDate, #EndDate), 0),
TotalCalls = COUNT(*)
FROM
IISLog AS I
WHERE
I.dDate BETWEEN #StartDate AND #EndDate
GROUP BY
I.Method

How can i take time difference from minutes and hour?

I need to take hour and minutes diff but also to convert it as this type hh:mm
Example if i will have a time 12:41 and 11:31 i need to take in output 01:10
Here is what i'm trying to do
SELECT DATEDIFF(MINUTE,datetime,getdate()) from Table_1
But i'm getting only minutes.
Example
Select convert(varchar(5),DateAdd(MINUTE,DateDiff(MINUTE,'2018-06-28 11:31','2018-06-28 12:41'),0),108)
Returns
01:10
For your live test
Select convert(varchar(5),DateAdd(MINUTE,DateDiff(MINUTE,datetime,GetDate()),0),108)
You could grab the datediff in mins and add it to an arbitrary date and cast it to TIME.
DECLARE #test1 TIME = '12:41'
DECLARE #test2 TIME = '11:31'
DECLARE #diff INT
SELECT #DIFF = DATEDIFF(MINUTE, #test2, #test1)
SELECT CAST(DATEADD(MINUTE, #diff, '1900-01-01') AS TIME)

SQL Query - Average time from datetime field

I'm struggling with what I thought would be a simple SQL query. Running SQL Server 2014
I have an SQL table, "Visits":
Id | EntryTime | Duration
And I want to find the average entry TIME OF DAY between two dates, taking into account all records between those dates.
so if my EntryTime field between my dates is:
2016-04-28 12:00:00
2016-04-20 10:00:00
2016-04-19 08:00:00
2016-04-17 10:00:00
Then the average time returned should just be:
10:00:00
The date should not be taken into account at all, and it should be returned in string format, or a manner which returns ONLY 10:00:00.
create table mytimes(
id int identity,
mydatetime datetime
)
insert into mytimes (mydatetime) values ('2016-04-28 12:00:00')
insert into mytimes (mydatetime) values ('2016-04-20 10:00:00')
insert into mytimes (mydatetime) values ('2016-04-19 08:00:00')
insert into mytimes (mydatetime) values ('2016-04-17 10:00:00')
SELECT Cast(DateAdd(ms, AVG(CAST(DateDiff( ms, '00:00:00', cast(mydatetime as time)) AS BIGINT)), '00:00:00' ) as Time )
from mytimes
-- where mydatetime between XXX and YYY
SELECT convert(varchar(8), Cast(DateAdd(ms, AVG(CAST(DateDiff( ms, '00:00:00', cast(mydatetime as time)) AS BIGINT)), '00:00:00' ) as Time ))
from mytimes
-- where mydatetime between XXX and YYY
output-1 10:00:00.0000000 - this is an actual Time type that you can do more with if needed
output-2 10:00:00 - this is output as a varchar(8)
Add your where clause as you see fit
The steps include
Casting to a Time type from a DateTime.
Using the AVG on Time, this is not supported by type Time so you have to first convert Time to milliseconds.
Converting the milliseconds back to a Time type
To avoid Arithmetic overflow error converting expression to data type int you can cast the result of DateAdd to a BigInt. Alternatively you can use seconds instead of milliseconds in the DateDiff function which should work unless your result set is overly large.
SO Sources:
T-SQL calculating average time
How to get Time from DateTime format in SQL?
Operand data type time is invalid for avg operator…?
SELECT CONVERT(TIME, DATEADD(SECOND, AVG(DATEDIFF(SECOND, 0, CONVERT(TIME, EntryTime ))), 0))
FROM Visits
WHERE EntryTime >= #begin AND EntryTime <= #end
The idea came from here: T-SQL calculating average time
Yap, you can use the Time() to get this done.
Your query becomes like this (modify accordingly)
SELECT COUNT(*) FROM Visits WHERE TIME(EntryTime) > '06:00' AND EntryTime < '18:00';

SQL Server : calculating days elapsed

I need to get the number of elapsed days between any two dates with respect to the current date. IE:
mm/dd/yyyy
Current day = 07/10/2015
07/08/2013 ... 07/11/2013 - 4 days elapsed
Current day = 07/10/2015
07/08/2015 ... 07/11/2015 - 2 days have elapsed
I've tried several combinations using DATEDIFF with day as the date part, however, I can't seem to get a clean way to get the days elapsed when the date could be past or present.
EDIT
I know the start date and the end date of a certain business process. They could be this year, last year, two years ago and so on. I need a way via SQL Server functions to figure out the days total elapsed. If it's not the current year, obviously the entire span/range would have elapsed. If it's the current year, perhaps the entire span/range hasn't elapsed and it needs to say how many days are "into the process" based on the respected start time, end time and current time.
Hopefully this makes more sense?
Please help.
I used #Sean Lange, with a small tweak:
DATEDIFF(DAY, #StartDate, case when #EndDate < GETDATE() then #EndDate + 1 else GETDATE() end)
Thanks all.
This is pretty similar to the answer provided by Stan but here is my take on this.
with Something as
(
select CAST('2013-07-08' as datetime) as StartDate
, CAST('2013-07-11' as datetime) as EndDate
union all
select '2015-07-08', '2015-07-11'
)
select *
, DATEDIFF(DAY, StartDate, case when EndDate < GETDATE() then EndDate else GETDATE() end)
from Something
How about this:
Given:
CREATE TABLE dbo.test ( ChildID INT Identity,
Start DateTime
, Finish DateTime
)
and your test data:
insert into dbo.test (start,finish) values('07/08/2013','07/11/2013')
insert into dbo.test (start,finish) values('07/08/2015','07/11/2015')
then
select start,finish
, DATEDIFF(DAY, start, CASE WHEN GETDATE() BETWEEN start and finish
THEN GETDATE() - 1 ELSE finish END) + 1 as elapsed
from dbo.test
gives the result from your example.
You might have to tweak if there are other adjustments for how the current date fits between the range.

Resources