Average difference between two dates, grouped by a third field? - sql

So say we have 3 fields, username, start_date, end_date
Users start and stop multiple records, eg below bob has started and stopped two records.
bob 1/2/13 11:00 1/2/13 13:00
jack 1/2/13 15:00 1/2/13 18:00
bob 2/2/13 14:00 1/2/13 19:00
I need to know the average time taken (ie diff between start and end), in hours, for each user (ie group by user, not just for each row).
I can't quite get my head around how to do the diff, average AND group by? Any help?

You don't specify the granularity you want for the diff. This does it in days:
select username, avg(end_date - start_date) as avg_days
from mytable
group by username
If you want the difference in seconds, use datediff():
select username, avg(datediff(ss, start_date, end_date)) as avg_seconds
...
datediff can measure the diff in any time unit up to years by varying the first parameter, which can be ss, mi, hh, dd, wk, mm or yy.

SELECT [username], AVG(TIMESTAMPDIFF(HOUR, start_date, end_date))
FROM [table]
GROUP BY [username]

Related

Calculate monthly rolling user count

I have a transaction data like this:
User_ID
Purchase_Date
12345
2022-08-02
12231
2022-06-25
12231
2022-07-15
13421
2022-07-12
23132
2022-05-02
15231
2022-04-09
I want to calculate a monthly rolling unique count of users which updates on a weekly basis. The week must be a full week that starts from Monday to Sunday.
Here is the desired output:
Unique_User_ID_Count
start_week_date
end_week_date
403
2022-07-04
2022-07-31
562
2022-06-27
2022-07-24
312
2022-06-20
2022-07-17
and so on.. data goes back 3 years
Using the code below, I am able to get the first row of the desired output but not sure how to get row 2 and 3 (and going back 3 years).
SELECT count(distinct user_id) as Unique_User_ID_Count, min(Purchase_Date) as start_week_date, max(Purchase_Date) as end_week_date
FROM table
WHERE Purchase_Date>= DATE_TRUNC(DATE_SUB(CURRENT_DATE(), INTERVAL 1 MONTH), WEEK(MONDAY)) AND Purchase_Date<= DATE_TRUNC(CURRENT_DATE()-6, WEEK(SUNDAY))
Any help is appreciated
You could use CTEs to compute the auxiliary data you need. With your starting dataset, I would do the following:
with data as (
select
User_ID,
Purchase_Date,
DATE_TRUNC(Purchase_Date, WEEK(MONDAY)) as start_week_date,
DATE_ADD(DATE_TRUNC(Purchase_Date, WEEK(MONDAY)), INTERVAL 6 DAY) as end_week_date,
from your_database
)
select distinct
count(distinct User_ID) over (partition by first_day_week, last_day_week) as Unique_User_ID_Count,
first_day_week,
last_day_week,
from data
That should work.
i think what you need is something like this..
select
DATEADD(DAY, 1-DATEPART(WEEKDAY, DateField)+1, convert(int,DateField)),DATEADD(DAY, 1-DATEPART(WEEKDAY, DateField)+7, convert(int,DateField)),count(*)
from Table1
group by DATEADD(DAY, 1-DATEPART(WEEKDAY, DateField)+1, convert(int,DateField)),DATEADD(DAY, 1-DATEPART(WEEKDAY, DateField)+7, convert(int,DateField))
if the data is big.. i d convert date to float then div to 7 then convert to int.. which i think can group the same results.. but then you are gonna have some more trouble in frontend..

How to get average of earliest datetime per day?

I need to get average time based on their earliest check in for each day.
For example, these are my check in datetime.
Person | Checkin
-----------------
Jack 2022-01-06 16:42:34.000
Jack 2022-01-06 17:30:34.000
Jack 2022-01-07 10:22:34.000
Jack 2022-01-07 12:12:54.000
Jack 2022-01-08 11:08:53.000
When I want to calculate my average check in time based on earliest check in, I should only consider these datetime.
2022-01-06 16:42:34.000
2022-01-07 10:22:34.000
2022-01-08 11:08:53.000
This is my current sql to get the average check in time. But this consider all the datetime above and gets the average time.
Select Person,(CAST(DATEADD(SS, AVG(CAST(DATEDIFF(SS, '00:00:00', CAST(Checkin AS TIME)) AS BIGINT)), '00:00:00' ) AS TIME)) AS 'AvgCheckInTime' from #Tab_CheckIn
group by Person
How can I only consider the earliest datetime for each day and get the average time?
This is a little messy.
Firstly you need to group the data to get the earliest checkin my day. That's quite simple, using CONVERT to date and MIN.
Then you need to get the "average" of those times. You can't average a time in SQL Server, however, as time represents a point in time during the day not an interval, so it doesn't make sense to average them like it would a timespan. As a result you need to "convert" the values to a numerical value.
In this case I use DATEDIFF to get the number of seconds since midnight to the checkin converted to a time. Then I can average those values, and finally add those second to midnight:
WITH Earliest AS(
SELECT Person,
MIN(Checkin) AS EarliestCheckin
FROM dbo.YourTable
GROUP BY Person,
CONVERT(date,Checkin))
SELECT Person,
DATEADD(SECOND,AVG(DATEDIFF(SECOND,'00:00',CONVERT(time,EarliestCheckin))),CONVERT(time,'00:00')) AS AverageCheckin
FROM Earliest
GROUP BY Person;
Assuming you get desired result(except filtering the undesired dates)
Select t.Person,(CAST(DATEADD(SS, AVG(CAST(DATEDIFF(SS, '00:00:00', CAST(t.Checkin AS TIME)) AS BIGINT)), '00:00:00' ) AS TIME)) AS 'AvgCheckInTime'
from (SELECT Person, min(Checkin) as Checkin FROM #Tab_CheckIn
GROUP BY Person, cast(Checkin As Date)) t
group by t.Person
SELECT Person,(CAST(DATEADD(SS, AVG(CAST(DATEDIFF(SS, '00:00:00', CAST(Checkin AS TIME)) AS BIGINT)), '00:00:00' ) AS TIME)) AS 'AvgCheckInTime'
from (
SELECT person, checkin, row_number() over(PARTITION by person, CAST(checkin as DATE) order by checkin asc) as row
FROM #Tab_CheckIn) as p
where p.row =1
group by p.person

How to calculate avg earnings/hour spent working by day of week?

I am trying to write a query to output the average earnings per hour spent dashing by day of week.
worker_table
session_id
worker_id
session_start
session_end
total_pay
num_of_deliveries
7712
9347
2020-08-31 03:32:43
2020-08-31 05:53:43
46.72
3
1560
5645
2020-07-26 01:48:40
2020-07-26 04:48:40
65.32
4
This is my query below but I am 99% positive it's incorrect. Please advise, thanks.
with t1 as
(select extract(dow from session_start) as dow, extract(hour from session_start) as start_hours, extract(hour from session_end) as end_hours, sum(total_pay) as total_pay
from worker_table
group by 1,2,3)
select dow, total_pay/(end_hours-start_hours)
from t1
order by 1
Try datediff function SQL Server
Select total_pay/DateDiff(hh,session_start,session_end),*
From table_name
Replace table_name with your table name in the database.

Count Number of hours between a range SQL

Im trying to count the number of working hours from some users for the month, the only way to do it is to see the date and hour for the productions entries they made. so I got:
Select a.EmployeeID, cast(a.fDate as Date) fDate, datepart(HOUR, a.fDate) fHour
From Table
Group by a.EmployeeID, cast(a.fDate as Date), datepart(HOUR, a.fDate)
This gives me the detail by date of the hours production was done, however I would like to know the total of hours in that time frame. For example:
I know employee xxx on 09/01/2018 registered production at 10:00AM, 11:00AM 12:00PM and 1:00PM, so the result will be 4 hours. Every employee has different working days so thats the only way I think I can calculated this...
Help?
Can you use the DATEDIFF of the min and max of fDate, group by EmployeeId and Date of a.fDate?
For example:
Select a.EmployeeID, cast(a.fDate as Date) as fDate, min(a.fDate) as TimeIn, max(a.fDate) as TimeOut, (DATEDIFF(mi, min(a.fDate), max(a.fDate)) / 60) as Hours
From MyTable a
Group by a.EmployeeID, cast(a.fDate as Date)

Average Time over a period of time in a SQL Query

Hello how would i be able to get the AVG of the Minimum time across records?
Meaning, I have these records:
Id Date Time Amount
1 7/1/14 9:00am 5.00
2 7/1/14 8:45am 6.00
3 7/1/14 9:30am 7.00
4 7/2/14 8:30am 4.50
5 7/2/14 9:15am 5.50
6 7/2/14 7:45am 4.75
now what i need is to get MIN of each day... so in this case it would be record 2, and 6.
but i want to some how average those times... meaning 8:45am and 7:45am ...
I want to know what is the average time first sale occurs over a time period. Not sure how to average out the time. So to say, over a given period, generally first sale occurs around say 8:20 am (estimating)
tx very much for any assitance
You can try somthing like this:-
SELECT Id, Date, AVG(Time)
FROM (SELECT Id, Date, MIN(Time) AS Time
FROM YOUR_TABLE
GROUP BY Id, Date) AS TABLE1
GROUP BY Id, Date;
This might be helpful to you.
To get the average, convert the time to seconds, compute the average and convert it back to a time.
SELECT Id, Date, SEC_TO_TIME(AVG(sec))
FROM (SELECT Id, Date, MIN(TIME_TO_SEC(Time)) AS sec
FROM YOUR_TABLE
GROUP BY Id, Date) AS TABLE1
GROUP BY Id, Date;
SELECT Format(( AVG(Table1.daTime) /86400),"hh:nn:ss") AS AvgTimeOfFirstTransaction
FROM (SELECT date, (MIN(Time) *86400) AS daTime
FROM transactions
WHERE ( (transactions.date)>=#7/1/2014# And (transactions.date)<#7/3/2014#)
GROUP BY transactions.date
) AS TABLE1