Sum the differences between dates - sql

I have 2 tables, master and detail, that both contain dates related to events. The first contain the master record's begin and end date. The second contains various gaps, that also have a beginning and an end, related to the master record and falling between its begin and end date.
I can successfully calculate the total number of days between the master record's start and end but, yet I'm failing to see how i can aggregate the sum of the "off days" in the details table and group them by month. With this i mean:
Master table
Start date (MM/DD/YYYY): 01/01/2015
End date (MM/DD/YYYY): 01/25/2015
Total number of days: 25
Details table
Start date (MM/DD/YYYY) | End date (MM/DD/YYYY) :
01/02/2015 | 01/05/2015
01/09/2015 | 01/15/2015
01/18/2015 | 01/19/2015
Total number of "off days": 13
The DB environment is Oracle 11g.
Can you help me?

Try this :
select sum(End_date-Start_date+1) from details_table;
The sum function will sum the total of all the dates, which should give you the 13 "off days" you wanted.
If you want to add the start_date/end_date conditions, you can do it like this.
select sum(End_date-Start_date+1) from details_table
where Start_date>=to_date('01/01/2015','mm/dd/yyyy')
and End_date<=to_date('01/25/2015','mm/dd/yyyy');

Related

Counting the Number of Days an Entry is Active within a particular month using a Date Range in Proc SQL

I am earning some data over a period of time but have hit a wall at figuring out some specifics.
For example I have a large number of rows of data that have an activity START and STOP date. I have performed a cartesian product to join my particular rows of data to that particular month if one of three cases occurs:
The Item Activity START date occurs before the first day of that particular month and that item's activity stop date occurs after the first day of that month. (ITEM_START<= CalendarMonthStart and ITEM_STOP>= CalendarMonthStart)
The Item Activity START date occurs after the first day of that particular month and that item's activity STOP date occurs before the last day of that particular month (activity is within the single month).(ITEM_START>= CalendarMonthStart and ITEM_STOP>= CalendarMonthEnd)
The Item Activity START date occurs before the last day of that particular month and STOPs after the last day of that particular month.(ITEM_START<= CalendarMonthEnd and ITEM_STOP>= CalendarMonthEnd)
An example of my proc sql query:
proc sql;
create table earned_activity as
select
a.ITEM_START,
a.ITEM_STOP,
b.MonthName,
b.CalendarMonthStart,
b.CalendarMonthEnd
/* Need to do something here */
from item_activity as a
left join calendar_table as b on
(ITEM_START<= CalendarMonthStart and ITEM_STOP>= CalendarMonthStart) or
(ITEM_START>= CalendarMonthStart and ITEM_STOP>= CalendarMonthEnd) or
(ITEM_START<= CalendarMonthEnd and ITEM_STOP>= CalendarMonthEnd)
;
quit;
After these three cases are joined to my data I have some example data like below:
ITEM_START
ITEM_STOP
MonthName
CalendarMonthStart
CalendarMonthEnd
num_days_active
2021-01-06
2021-03-06
Jan
2021-01-01
2021-01-31
25
2021-01-06
2021-03-06
Feb
2021-02-01
2021-02-28
28
2021-01-06
2021-03-06
Mar
2021-03-01
2021-03-31
6
As you can see, with the cartesian product I have an item with activity in three different calendar months. I would like to find a way to get the # of days that item existed in each of these months. My first idea would be to perform a cartesian product on each individual days of the month and somehow tally up if that day was active but I believe that might get massive and cumbersome quite quickly. Is there a good approach to performing this type of operation?
Thank you.
You just need a max of the start and min of the end, I think.
SELECT
DATEDIFF(day,
CASE WHEN CalendarMonthStart > a.ITEM_START THEN CalendarMonthStart ELSE a.ITEM_START END,
CASE WHEN CalendarMonthEnd < a.ITEM_STOP THEN CalendarMonthEnd ELSE a.ITEM_START END)
Furthermore, your WHERE can be much simpler:
inner join calendar_table as b on
(ITEM_START <= CalendarMonthEnd and ITEM_STOP => CalendarMonthStart)

How can I calculate the number of minutes per day between a daterange

First off I apologize I do not even know where to start and haven't been able to find anything specific to this particular question.
I have a table with datetimes (start and end) and i need to find a way to get minutes/hours between those days. It could either be a sum of the time on weekdays or a some kind of pivot on each day and grouping by the ID number. I had thought to assign a value to the number of days however the times are random and do not start/end at midnight so I am at a loss as how to approach this.
Here are some examples of the date/time format if that helps.
startdate 2018-12-14 10:53:01
enddate 2018-12-27 11:50:00
Any helps or hints would be greatly appreciated!
Edit
forgot to include I am working in SQL Server (SSMS)
Editing For Additional Clarification
Here is a sample date range with an ID number, I wanted to keep it simple.
|ID number| start time |end time
|1 |12/14/2018 10:53|12/17/2018 12:00
here is what I'm trying to achieve (the separation of each date range/ID #)
ID number| start time |end time |mins|
1 | 12/14/2018 10:53|12/14/2018 23:59|786 |
1 | 12/15/2018 0:00 |12/15/2018 23:59|1439|
1 | 12/16/2018 0:00 |12/16/2018 23:59|1439|
1 | 12/17/2018 0:00 |12/17/2018 12:00|960 |
The MINUTE parameter of the DATEDIFF function can be used to determine the difference in minutes between two datetime columns. As below, the second parameter is the start date and the third parameter is the end date, with the result being the amount of time in the specified interval (days, minutes, etc.) from the start to the end date. If you need to find the number of hours between these two columns the HOUR parameter can be used for this. Grouping can be performed as well, as in the second example.
DATEDIFF:
SELECT DATEDIFF(MINUTE, StartDateColumn, EndDateColumn)
DATEDIFF with Grouping and Aggregation:
SELECT ColumnA, SUM(DATEDIFF(MINUTE, StartDateColumn, EndDateColumn)) as DifferenceInMinutes
FROM YourSchema.YourTable
GROUP BY ColumnA

How to find the leave balance month wise in teradata

I have sample data like this
EmployeeID Begin Date End Date Duration
168835 28/11/2017 28/11/2017 6
168835 31/10/2017 9/11/2017 32
and I want to find the leave taken by this employee month wise,so i have joined with calendar date and i want to summarise this data monthly.For e.g, he has taken leave from 31/10/2017 to 9/11/2017 for 32 hours and 6 hours in 28/11/2017. I want to exclude weekend from 31/10/2017 to 9/11/2017 period. I have used "day of week" flag to exclude the weekends, but now problem is when i roll up the data its giving me incorrect result. basically, i want to data like duration (32+6)=38 and this should be divided no of working days that is 9 in this case, so in oct month my data should be 4.22 and in nov month it should 33.77. can anyone please help me on this.Thanks in advance.

How to insert a record on next selected date if count of a date is full

I have a table where I maintain working days in a week like 2nd and 4th day and number of records it can accept is 10 records per working day
usercode DaysofWeek NumberOfRecords
0623PO54 2 10
0623PO54 4 10
On insertion I have application date example 01-09-2017(dd/mm/yyyy) which is Friday.
Now I have to insert this record in closest working day from 01-09-2017 which is 05-09-2017 as it is 2nd working day. After inserting 10 records next records should be insert on 4th working day which is 07-09-2017.
I don't know how to get closest date from application date and insert record on it.
If you also want to exclude holidays than use a master table for Ex. CalenderMastr of dates which have holidays flag and day of week like Monday=2. and as you mansion that you are maintaining working days in a table for ex. workdaymaster. Now make a select query to get next date from CalenderMastr from current date and day of week stored in workdaymaster. now on output date check if in your transaction table count is smaller or not if count is small insert new record or if not than move to next date using while loop in your query. hope you can understand what i am trying to say.

Cumulative count in SQL

I am working on SQL and came across one scenario that needs to build in SQL.
Below is scenario:
PatientID AdmitDate DischargeDate
12 7/24/2017 09:45 7/24/2017 11:01
13 7/21/2016 08:37 7/22/2017 00:15
I want result set as below:
For patientID 13, count is calculated in first 2 rows and
For patientid 12, count is calculated in last row.
Well, that looks like whatever you do will be slow. I think I'd use a tally table. The table, instead of just containing the usual n years worth of dates / days / day of week etc. would also contain one record for each hour in the day. The Primary Key would represent one of those segments.
Then you could pass the admission date and discharge date for a patient to a function that would return a list, or range, of the hours that the patient is in for. So, Patient 13 might get a return value of (for example) 1500,1517 (i.e the patient was in for 17 hours and you will know the date and time because 1500 will be the Primary Key of a record that gives you the date and hour of the day he was admitted). Patient 12 would (to continue the example) return a value of 1544,1546
You could then build the dataset from Date A to Date B by returning all the data between those dates from the tally table and then check whether each hour is a yes or no for a particular patient.
The display of the data - your desired result set - I would do in somewhere else. I'd probably return two datasets. One would be used to build your table structure. The other would be used to decide whether to put a '1' in the box or not. You could do your summing on the fly.
I imagine this would get interesting with patients on the same dates ... you'd have to show each patient separately?