I have a table containing areas whose size changes over time. The timeframe (in years) for which an area size is valid is stored in the columns "VALID_FROM" and "VALID_UNTIL". The timeframes for one area must not overlap. I want to create a query with which I can check if someone has entered overlapping timeframes.
In the example table the validity timeframes from area1 do overlap.
Table "areas":
NAME | SIZE | VALID_FROM | VALID_UNTIL |
---|---|---|---|
area1 | 55 | 1990 | 2005 |
area1 | 40 | 2000 | 2009 |
area1 | 45 | 2010 | 2099 |
area2 | 79 | 1990 | 2099 |
area3 | 33 | 1990 | 1999 |
area3 | 37 | 2000 | 2009 |
Note that end dates are inclusive e.g. there is no gap in the two dates for area3.
It would be sufficient to have a result like this:
NAME | REMARK |
---|---|
area1 | ‘timeframes overlap!’ |
My problem is that an area may occure n times in the table, I dont know how to compare the "VALID_FROM" and "VALID_UNTIL" columns if there could be an arbitrary number of rows for one area.
So far I got as far as reducing the table to those rows which occur more than once.
WITH duplicats AS (
SELECT `NAME`
FROM `areas`
GROUP BY `NAME`
HAVING COUNT(`NAME`) > 1
)
SELECT *
FROM `areas`
INNER JOIN `duplicats`
ON `areas`.`NAME` = `duplicats`.`NAME`
4
Answers
You can do it by self join your tables :
Result :
Or if you want result grouped by area then :
Result :
Demo here
To test for overlaps you would simply:
The two from-until date comparisons are sufficient to find all kind of overlaps. The answer assumes until date is inclusive.
In MySQL 8.x, you could subtract the previous
valid_until
value from thevalid_from
value, if there is a negative difference then there is an overlap.demo
JOIN
a calendar table or cte. Do aGROUP BY
and useHAVING
to find years having two (or more) rows with the same area.