Finding in between which two dates in a column the target date is - sql

Got a table that I am trying to clean up and can't figure out how to find a record where one date falls between two dates in the actual columns
TargetDateTime Location TransferDateTime
01/01/2014 1:00 PM Room 1 01/01/2014 10:00 AM
01/01/2014 1:00 PM Room 2 01/01/2014 12:30 PM
01/01/2014 1:00 PM Room 3 01/01/2014 01:30 PM
01/01/2014 1:00 PM Room 4 01/01/2014 03:00 PM
TransferDateTime marks the time when a person was moved to the room
TargetDateTime marks some event that a person did.
In this example, TargetDateTime is 1:00 PM; therefore the event took place in Room 2 because 1:00 PM falls between 12:30 PM and 1:30 PM.
What would be the best way in SQL to select only that row and ignore the rest?
Thanks a bunch for any suggestions!

Based on your sample data and guessing that you have groups of the same TargetDateTime, the following should do it.
;WITH MyCTE AS
(
SELECT TargetDateTime,
Location,
TransferDateTime
ROW_NUMBER() OVER (PARTITION BY TargetDateTime ORDER BY TransferDateTime) AS rn
FROM TableName
WHERE TransferDateTime >= TargetDateTime
)
SELECT *
FROM MyCTE
WHERE rn = 1

Related

Exclude overlapped time period

I wish to write a query for below problem.
The problem is, I want to eliminate all overlapping periods, so that I get the total amount of time which is not taken in any other row.
Example:
NAME
Start Date Time
End Date time
Load shed
21-03-2020 12:30
21-03-2020 13:30
Shutdown
21-03-2020 13:00
21-03-2020 14:00
breakdown
21-03-2020 13:10
21-03-2020 14:10
Load shed
24-03-2020 12:30
24-03-2020 13:30
Shutdown
24-03-2020 11:00
24-03-2020 19:00
breakdown
24-03-2020 13:10
24-03-2020 14:10
Now what we have to do is:
Return time period between start date time and end date time but exclude overlapped time.
Expected result will be:
NAME
Start Date Time
End Date time
Time_interval
Load shed
21-03-2020 12:30
21-03-2020 13:30
01:00
Shutdown
21-03-2020 13:30
21-03-2020 14:00
00:30
breakdown
21-03-2020 14:00
21-03-2020 14:10
00:10
Shutdown
24-03-2020 11:00
24-03-2020 19:00
08:00
Now we can see in result,
First row: As it is because it has the lowest start date time in all
overlapped rows.
Second row: 30 minutes already used in first row so
we exclude 30 minutes here and write left time interval.
Third row:
we exclude till time 14:00 because its already used in row 2 so now time
interval has 10 minutes only.
Fourth row: We exclude all rows from
given table because they all overlapped and they are within start date
time 24-3-2020 11:00 and 24:03:2020 19:00 .
Hope you understand the problem.
Thanks in advance.
You can calculate the previous enddt before each row. Then, if that is larger than the start date, use that for the row. And, if the duration of the row is negative, then filter out the row.
The code looks like:
select name, imputed_startdt, enddt, prev_enddt,
convert(time, dateadd(minute, datediff(minute, imputed_startdt, enddt), 0)) as duration
from (select t.*, max(enddt) over (order by startdt rows between unbounded preceding and 1 preceding) as prev_enddt
from t
) t cross apply
(values (case when prev_enddt > startdt then prev_enddt else startdt end)
) v(imputed_startdt)
where prev_enddt < enddt or prev_enddt is null;
Here is a db<>fiddle.

SELECT COUNT Per Date and Type SQL Server 2012

I have an SQL Query below.
SELECT sched_date, sched_name, employee_name from tbl_schedule
It returns this result:
sched_date sched_name employee_name
2017-04-01 09:00 AM - 06:00 PM M.G.Cave
2017-04-01 09:00 AM - 06:00 PM L.C.Manalo
2017-04-01 11:00 AM - 8:00 PM R.M.Jakosalem
2017-04-01 11:00 AM - 8:00 PM S.D.Dela Cruz
2017-04-02 Rest Day M.G.Cave
2017-04-02 Rest Day L.C.Manalo
2017-04-02 Rest Day R.M.Jakosalem
2017-04-02 Rest Day S.D.Dela Cruz
I want the employees to be counted per date and per schedule. My desired result is:
2017-04-01 09:00 AM - 06:00 PM 2 employees
2017-04-01 11:00 AM - 8:00 PM 2 employees
2017-04-02 Rest Day 4 employees
Thank you in advance.
A GROUP BY on the sched_date, sched_name and a COUNT(*) will get you your desired result:
SELECT
sched_date,
sched_name,
COUNT(*) AS employees
from
tbl_schedule
GROUP BY
sched_date,
sched_name
Try below query :
SELECT *
FROM
(
SELECT sched_date, sched_name, COUNT(*) AS employees
FROM tbl_schedule
GROUP BY sched_date,sched_name
) A

sql missing date query

Having a table with these records:
01-JAN-15 10:00
01-JAN-15 11:00
01-JAN-15 13:00
01-JAN-15 14:00
01-JAN-15 15:00
01-JAN-15 18:00
01-JAN-15 19:00
It's 1h resolution, so in my example 12:00, 16:00 and, 17:00 are missing.
I would like to create an SQL query that returns something like this (missing hour start, and duration):
01-JAN-15 12:00, 01:00
01-JAN)15 16:00, 02:00
Any suggestion?
Assuming your values are datetime values, then you can do something like this:
select t.*,
datediff(hour, datetimecol, next_datetimecol)
from (select t.*,
lead(datetimecol) over (order by datetimecol) as next_datetime
from t
) t
where next_datetimecol is not null and
dateadd(hour, 1, datetimecol) < next_datetimecol;
Depending on your data types and the precision, this might not work exactly. But the idea is basically the same . . . use lead() to get the next value and do some comparisons.

How to count the records per half hour from a period (datetimefrom and datetimeto) field?

I have a table which looks like you can see below:
Id Date ScheduledTimeFrom ScheduledTimeTo ActualTimeFrom ActualTimeTo
1 2013-01-01 1899-12-30 07:00:00 1899-12-30 18:00:00 1899-12-30 07:23:00 1899-12-30 17:15:00
I need to calculate per half hour how many records exists, the output should be like:
Time Actual Count:
7:00 4
7:30 4
8:00 4
8:30 4
9:00 4
9:30 5
10:00 5
10:30 6
11:00 7
11:30 8
12:00 8
12:30 8
13:00 8
13:30 8
14:00 8
14:30 8
15:00 7
15:30 7
16:00 7
16:30 6
17:00 5
17:30 4
18:00 4
I already tried to make a helper table which should hold the times per halfhour. I have joined this helpertable with the table that contains the data and after that I tried to use a group by function but it was not working.
My query was like:
Create table period (timefrom datetime, timeto datetime)
insert into period
select '1899-12-30 07:00:00.000', '1899-12-30 07:30:00.000'
Union all
select '1899-12-30 07:30:00.000', '1899-12-30 08:00:00.000'
select *
from period p left join table1 t on t.ActualTimeFrom < p.timeto and t.ActualTimeTo >=p.timefrom
Grouping this give me no desired result....
Anyone an idea how to come to the result?
P.s. I am using sql server 2005.
After snooping around and testing it on my side, looks like this date function could be the answer:
DATEADD(mi,DATEDIFF(mi,0,YOUR_DATE_COLUMN)/30*30,0)

Need help in finding nearest shift time in SQL

I have following table for shifts.
AutoId StartTime EndTime
1 08:00:00 AM 04:00:00 PM
2 04:00:00 PM 12:00:00 AM
3 12:00:00 AM 08:00:00 AM
Now I want to assign Shifts to employees automatically..
For example, if someone comes 7:32 AM then his shift should be the first shift, that is, from 08:00:00 AM to 4:00:00 PM. If someone comes 11:45 PM then it should be automatically set as the third shift.
I also want that if an employee come in during the first hour of the shift then it should also work.
How do I find the nearest shift by giving employee InTime?
Something like:
SELECT AutoId, StartTime, EndTime
FROM Shifts
WHERE StartTime = (SELECT MIN(StartTime) FROM Shifts WHERE DATEADD(hh, 1, StartTime) > inTime)
EDIT: Added grace period