I have a table of date ranges that often overlap.
I want to
adjust the date range if it overlaps with an earlier date range
normalize
Get sum of overlaps
Get # of records merged
Example
Start Date
End Date
2018-01-02
2018-01-04
2018-01-05
2018-01-07
2018-01-07
2018-01-10
2018-01-12
2018-01-15
Step 1 . Adjust date range if it overlaps with an earlier date range
Start Date
End Date
2018-01-02
2018-01-04
2018-01-05
2018-01-07
2018-01-08
2018-01-11
2018-01-12
2018-01-15
Step2: Normalize, Get sum of overlaps, and count of records merged
Start Date
End Date
Overlap
Ct
2018-01-02
2018-01-15
1
4
I'm using Teradata.
I've previously used NORMALIZE ON MEETS AND OVERLAPS to normalize but I don't know how to get the amount of overlap and the count of records that were merged.
I've though of using NPATH but I can't figure out how to calculate amount of overlap.
(Teradata NORMALIZE options)
Related
Question
I have a table that holds all the work experience of each employee. I want to get all work experience of employee that overlapped the dates. Below is the sample.
Scenario
Employee 1 have a total of two (2) work experience.
Employee 2 have a total of three (3) work experience.
tbl_work_exp
employee_id
start_date
end_date
1
2021-01-01
2021-06-30
1
2021-07-01
2021-12-31
2
2021-01-01
2022-02-01
2
2021-07-01
2021-12-31
2
2022-01-01
present
3
---
---
4
---
---
5
---
---
and so on...
The first row of Employee 2 overlap the dates to its present work experience.
What I need is to get all rows that overlap the dates, like the table below.
Results
employee_id
start_date
end_date
2
2021-01-01
2022-02-01
2
2021-07-01
2021-12-31
2
2022-01-01
present
Thank you in advance.
I have an issue with one SQL query in MySQL. My table looks like below:
Index User Date Speed
1 X 2018-01-01 10:00:00 23
1 X 2018-01-01 10:00:20 50
1 X 2018-01-02 10:00:00 40
1 Z 2018-01-01 10:00:00 20
1 Z 2018-01-02 10:00:00 40
1 Z 2018-01-03 10:00:00 50
and result should be like this:
Index User Date Speed Date_diff Speed_diff
1 X 2018-01-01 10:00:00 23
1 X 2018-01-01 10:00:20 50 20s 27
1 X 2018-01-01 10:02:00 40 1m40s -10
1 Z 2018-01-01 10:00:00 20 -2m -20
1 Z 2018-01-02 10:00:00 40 1d 20
1 Z 2018-01-03 10:00:00 50 1d 10
So basically I need to substract rows one after another and create a new columns one with results. I am starting an adventure with SQL and I am not sure how I could do this? Any idea?
I tried to do this using this https://dev.mysql.com/doc/refman/8.0/en/window-function-descriptions.html#function_lag but I think that my syntax is wrong
SELECT objid,
LAG(Date) OVER AS 'lag',
LEAD(Speed) OVER AS 'Lead',
date- LAG(date) OVER AS 'lag diff',
speed- LEAD(speed) OVER AS 'Lead diff',
FROM tabel;
Try something like:
SELECT Index, User, 'Date', Speed,
'Date' - LAG('Date') OVER w AS Date_diff,
Speed - LAG(Speed) OVER w AS Speed_diff
FROM table
WINDOW w AS (ORDER BY User, 'Date');
Only use single quotes for string and date values -- never for column names.
Your code also needs a windowing clause, and to adjust the date/time arithmetic. If you can represent the date/time difference as a time, then:
SELECT t.*,
secs_to_time(to_seconds(t.date) - LAG(to_seconds(t.date)) OVER (PARTITION BY user ORDER BY DATE)) AS date_diff
(t.speed - LAG(speed) OVER (PARTITION BY user ORDER BY DATE)) as speed_diff
FROM tabel t;
My actual table is much more in-depth than this but let's assume I have a table that looks like this...
Record_ID Due_Date Style
========= ========== =====
100 2018-01-01 10
101 2018-01-02 20
102 2018-01-03 12
103 2018-01-04 10
104 2018-01-05 20
105 2018-01-06 12
106 2018-01-02 10
What I want is a query that will determine the first due date and then return that record along with all other records with the same style regardless of the due date. It should then be followed by the next due date of another style and keep going. A successful output would be in this order...
Record_ID Due_Date Style
========= ========== =====
100 2018-01-01 10
106 2018-01-02 10
103 2018-01-04 10
101 2018-01-02 20
104 2018-01-05 20
102 2018-01-03 12
105 2018-01-06 12
If you look at just the first record for each Style the output is in order.
See records 100,101,102
If you look at all the records for a given Style the output is sorted by date.
See records 100,106,103
If you look at just the Style column the output is has all the like Style together but not necessarily in numerical order.
By doing having this output, it is easy to see what Style is due first but all records in that same Style will be completed prior to moving on to the next Style
Here's one option using a subquery that creates a grouping of styles with their corresponding min(duedate). Then you join that back to the original table and order by that date.
select *
from yourtable t join (
select min(duedate) minduedate, style
from yourtable
group by style) t2 on t.style = t2.style
order by t2.minduedate, t.duedate
Online Demo
I have a table with several events and their starting and ending date/time.
Below I have a sample data with 4 events which overlaps simultaneosly in different periods of time.
For each period they overlap I should apply a multiplying factor to its duration.
What I've got so far:
I am using MySQL as a database;
I have a table with spatial index on the start/end date/time which I use with MBRIntersects to find overlaps among the events. The method works pretty fine, and I got rid of those many ifs and joins.
Thus, I can get the intersection start/end time of each event individually. But that doesn't help much.
I need to find the start/end time of the overlapping periods, so I can group them and apply the maximun factor in that range.
Maybe I am taking the wrong approuch.
What I cannot do so far: Find the start/end times of the overlapping periods. In the example shown I need to get intervals like so:
1 | 08:00 | 08:15
2 | 08:15 | 09:30
3 | 09:30 | 10:00
4 | 10:00 | 10:15
5 | 10:15 | 10:30
6 | 10:30 | 11:00
I am using MySQL, I have following table structure
Id id2 classId sectionId validFrom validTill
------------------------------------------------------
1 1 5 13 2016-01-01 2016-03-30
2 1 5 22 2016-01-15 2016-03-30
3 1 5 23 2016-01-15 2016-04-29
4 1 5 13 2016-04-01 2016-04-30
9 10 6 24 2016-01-17 2016-02-05
10 10 6 25 2016-01-23 2016-02-05
11 10 6 24 2016-01-31 2016-02-05
My SQL statement is
SELECT count(*) as timeCount FROM TimeTableClassSection a
WHERE classId=5 AND sectionId=13 AND ((a.ValidFrom BETWEEN '2016-01-18' AND '2016-01-24') OR (a.ValidTill BETWEEN '2016-01-18' AND '2016-01-24'))
Its returning timeCount = 0. But it should return 1 as record with Id=1 falls between this date range ('2016-01-18' AND '2016-01-24')
I am trying to achieve, find out any overlapping record for particular classId & sectionId between provided date range.
If classId=5 and sectionId=13 has validFrom=2016-01-01 validTill=2016-03-30 exist, then any date range between this date range ('2016-01-18' AND '2016-01-24') should throw this record as count.
If I give date range 2015-12-25 to 2016-09-20 then record count should = 1
If I give date range 2016-2-1 to 2016-02-20 then record count should = 1
If I give date range 2016-2-1 to 2016-09-20 then record count should = 1
What wrong I am doing here ... all date format is in YYYY-MM-DD
You are only checking if the boundaries are within the date range, but you do not check whether the data range is within the boundaries. You should extend your where criteria:
...AND ((a.ValidFrom BETWEEN '2016-01-18' AND '2016-01-24')
OR (a.ValidTill BETWEEN '2016-01-18' AND '2016-01-24')
OR (a.ValidFrom<'2016-01-18' AND a.ValidTill>'2016-01-24'))