Let's say I have an employees list and I log inside "log" table the beginning and the end of the employee working day. Example:
ID
NAME
BEGINTIME
ENDTIME
1
Mary
05/04/2021 07:10
05/04/2021 10:10
2
John
05/04/2021 09:10
05/04/2021 14:10
And I want to search: how many employees where working at the same time (interval) and the number of them (if more than 1) and sort them from max to min.
Example: Mary and John were working at the same time May 4th from 09:10 to 10:10, before 09:10 Mary was alone, then John came at 10:10 and they were two employee working at the office (the max in that example) then Mary left the office at 10:10 and John was alone.
The point is due to COVID19, I want to know for on a specific date (May 4th in that example) when we had the more employees working in the office at the same time, to split them to lower that max.
Exepected result (the first row is to define the aim) :
MAXEMPLOYEES
FROMBEGINTIME
TOENDTIME
LISTAGG
120
dd/MM/YYYY HH:mm
dd/MM/YYYY HH:mm
...
2
05/04/2021 09:10
05/04/2021 10:10
Mary, John
I really don't know where to start, maybe I thought, find all the log for the May 4th (let's say 1000 row) and loop, first row then loop again to the other logs and if MYSELECTEDROWBEGINTIME >= NthBEGINTIME AND MYSELECTEDROWENDTIME <= NthENDTIME and loop to my list and then go the 2nd row etc.
For 12-12:30 interval, you can start working on this query:
select count(*) employees_count
from log
where begintime<to_date('05/04/2021 12:30','MM/DD/YYYY HH24:MI')
and endtime>to_date('05/04/2021 12:00','MM/DD/YYYY HH24:MI');
I'm assuming that the begintime and endtime are of date type. In general, your condition should be begintime<interval_endtime and endtime>interval_begintime.
For your example output in your original post, you may need a table for the time interval to be joined to log, which would look like this:
int_id
int_from
int_to
1
09:10
10:10
2
12:00
12:30
and your query for May 4, 2021 can be something like this:
select count(*) maxemployee,
int_from frombegintime,
int_to toendtime
from (
select log.id, log.begintime, log.endtime,
tint.int_from, tint.int_to
from log
join time_interval tint
on log.begintime<to_date('05/04/2021 '||tint.int_to,'MM/DD/YYYY HH24:MI')
and log.endtime>to_date('05/04/2021 '||tint.int_from,'MM/DD/YYYY HH24:MI')
) t
group by int_from, int_to
Related
I have an Oracle table filled with call information. I have the call datetime field (calldate). Each record represents one call. How do I find the average number of calls per hour by year?
Sample data:
Calldate Account Name
1/20/2016 10:16:09 AM 12345 Blee
1/20/2016 11:17:02 AM 45678 Foo
Something like:
1:00 AM 23
2:00 AM 22
3:00 AM 19
Thank you!
Something like:
select to_char(calldate, 'YYYY-HH24') as yyyyhh,
count(*) / count(distinct trunc(calldate)) as avg_per_hour
from t
group by to_char(calldate, 'YYYY-HH24')
order by yyyyhh;
Note: This treats days with no calls as NULL, rather than zero.
I need to get the difference between 2 date time in minutes(Time difference in minutes). And the last difference will be calculated based on 6 PM of every date.
Sample data: need result of last column
User_Name Date Time difference in minutes
User 1 1/1/06 12:00 PM 30
user 2 1/1/06 12:30 PM 315
user 3 1/1/06 5:45 PM 15
Here the date will be always in same date and the last user date difference calculated based on default value 6PM. Assuming the dates of any user will not cross 6PM time.
Please suggest how to write the query for the same.
You could use the lead window function.
I assume your table is called mytable and the date column is mydate (it is a bad idea to call a column Date as it is a reserved word).
select user_name,
round((lead(mydate, 1, trunc(mydate)+18/24)
over (partition by trunc(mydate) order by mydate)
- mydate) *24*60) as difference
from mytable
I found the solution.. if its not correct let me know
SELECT User_name,created_date,
trunc(to_number((cast(nvl(lead (created_date,1) OVER (ORDER BY created_date),TRUNC(SYSDATE) + (19/24)) as date) - cast(created_date as date)))*24*60) as difference
FROM users;
I am writing a SELECT query in MS Access. There is a child table (one to many) where each person has multiple records with different EndDate like the following:
Schedule Table
ID StartTime EndTime AssignmentEndDate
1 6:00 12:00 01/01/2016
1 6:00 12:00 06/30/2016
1 6:00 12:00 01/01/9999
From the record, there are 3 AssignmentEndDate records. I need to fetch the record with the Date closest to Today's date, but not passed it yet. Today is 06/13/2016 so, I need to
fetch the 2nd record with AssignmentEndDate 06/30/2016. If today is 7/13/2016, it would be the record with Date of 01/01/9999.
I can't use Max()... So how can I write a SELECT that will do this?
Thanks
You can do this as:
select top 1 s.*
from schedule as s
where assignmentdate > Date()
order by assignmentdate asc;
I have a requirement in SQL where I have data of a server start stop time on daily basis for one month. I need the result where it should calculate the first start time of the day, last stop time of the day, total time server was started in a day on daily basis and for servers.
Table is like below and expected output is also given.
Table:
Date & Time Reader ServerID
3/14/2016 6:36:20 AM ON 123
3/14/2016 6:58:45 AM OFF 123
3/14/2016 8:06:19 AM ON 123
3/14/2016 9:32:48 AM OFF 123
3/15/16 6:00:00 AM ON 123
3/15/16 6:01:00 AM OFF 123
3/14/2016 9:46 AM ON 124
3/14/2016 10:01 AM OFF 124
3/14/16 11:01 AM ON 124
3/14/16 12:01 PM OFF 124
Expected output
UserID FirstIN Last Out TotalInTime (min) Date
123 6:00 09:32 86 3/14
123 06:00 06:01 1 3/15
124 9:46 12:01 75 3/14
So, for each day & server, you want the minimum and maximum time and the sum of minutes "ON".
First you need rows of ON/OFF pairs (pairs on a row, not pairs of rows) whose minutes you can calculate. Then you sum the minutes and take the minimum and maximum times.
SQL Server has datepart. You can use that to compute days. To make On/Off pairs, join the table to itself along these lines:
select A.ServerID, datepart(day, A.time) as day,
A.time as ON, min(B.time) as OFF
from T as A join T as B on datepart(day, A.time) = datepart(day, B.time)
and A.Reader = 'ON' and B.Reader = 'OFF'
and A.time < B.time
group by A.ServerID, datepart(day, A.time), A.time
You can make a view like that, or a CTE, or insert the results in a temporary table. Let's call the result V.
select ServerID, day, min(ON), max(OFF)
, sum(datediff(minute, OFF, ON)) as minutes
from V
group by ServerID, day
(You can also nest the first query inside the second one.)
The trick is knowing how to find the "next" time for any pair (a question I've answered often), and how to use the server's date functions.
Working from an oracle 10g environment.
Suppose you were given: *NOTE (Duration is in Weeks)
CLASSNAME INSTURCTOR DAYS STARTDATE *DURATION TIMESTART TIMEEND
------------------------- ----------------------- ------------- --------- -------- --------
Power Dance Robert Backman MWF 03-MAR-11 2 0930 1100
Power Dance Lynn Parker MWF 03-MAY-11 2 0930 1100
Power Dance Lynn Parker MTTh 18-MAY-11 2 1230 0100
Club Stretch Kevin Lopez MT 24-OCT-11 3 1930 2015
Club Stretch Kevin Lopez F 17-JUN-11 3 1130 1300
Hatha Yoga Susan Wanzer MW 25-MAY-11 3 1900 2000
A user wants to be able to query the Classname, Instructor, Timestart, and TimeEnd for a class given a specific date.
I understand how to find the EndDate using (Duration * 7) + StartDate. The trouble I am having is finding out which classes are running on a day of the week. As in say the user enters in 24-JUN-11, the only class that should show up should be Club Stretch.
It might be just a matter of rephrasing your question: you want to know which classes are starting at of before the specified date and are ending at or after this specified date.
You already have the starting date and you know how to calculate the ending date.
This will be your solution:
SELECT [columns]
FROM [table]
WHERE #specifiedDate BETWEEN [startDate] AND [calculatedEndDate]
AND [days] LIKE #specifiedWeekday
#specifiedWeekday should, when looking for a Monday, have a value like this (in MS SQL): '%M%'
NOTE: Just now read your working in Oracle. This is a SQL Server answer. I hope the idea behind it will help you along.
Looks to me that you need to first determine the day of the week store that as a variable that you would feed to the second to the second query. Query sample for first part below:
select to_char(to_date('31-May-2011','dd-Mon-yyyy'),'DAY') from dual
SQL> /
TO_CHAR(T
---------
TUESDAY
or
select to_char(to_date('31-May-2011','dd-Mon-yyyy'),'DY') from dual
TO_
---
TUE
then you could feed that into your other query with your now known day of the week. If you need to decode it to the formats you mention then the following code will convert the day of the week to the abbreviations you are showing:
select decode(to_char(to_date('26-May-2011','dd-Mon-yyyy'),'DY'), 'MON','M',
'TUE','T',
'WED','W',
'THU','Th',
'FRI','F',
'SAT','Sa','Su')
from dual
will return the Th you are using :)