views:

51

answers:

1

I am creating a stored procedure that produces reports based on data in a SQL database and stores these reports in a separate database. The data being reported is the total time over a date range that a motor was running. I want to be able to detect if the timeframe I am reporting overlaps previous reports based on date times.

For instance we have the following table:

Row-----Value-----StartDate------------------EndDate
1-------12--------2010-01-21 00:00:00.000----2010-01-21 11:59:99.997   
2-------12--------2010-01-22 00:00:00.000----2010-01-22 11:59:99.997
3-------12--------2010-01-22 12:00:00.000----2010-01-22 23:59:99.997
4-------12--------2010-01-23 00:00:00.000----2010-01-23 11:59:99.997
5-------12--------2010-01-24 00:00:00.000----2010-01-24 11:59:99.997

If I were to insert the following rows into this table:

INPUT:

 1. Value = 12, StartDate = 2010-01-21 6:00:00.000, EndDate = 2010-01-21 17:59:99.997
 2. Value = 14, StartDate = 2010-01-21 11:00:00.000, EndDate = 2010-01-22 0:59:99.997
 3. Value = 13, StartDate = 2010-01-20 12:00:00.000, EndDate = 2010-01-21 0:59:99.997

OUTPUT:

 1. Value = 6, StartDate = 2010-01-21 12:00:00.000, EndDate = 2010-01-21 17:59:99.997
 2. Value = 12, StartDate = 2010-01-21 12:00:00.000, EndDate = 2010-01-21 23:59:99.997
 3. Value = 12, StartDate = 2010-01-20 12:00:00.000, EndDate = 2010-01-20 23:59:99.997

As you can see, the start/end dates are adjusted and the extra time is removed. It is important to note that the results are if only 1 row is added, not all 3 at the same time.

I think I've looked at the problem too long and am not seeing the forest for the trees. However, in the process of writing this question I have come up with some more ideas to try as well as modifications to make to my tables, but would still like to see how you guys would approach this situation.

Question: What query would you use to detect that a start and end date over lap other date ranges across multiple rows?

Cheers!

* Edit *

To clarify my example data, the Value=6 for output 1 comes from the fact that it conflicts with row 1 by 6 hours. Below is the changes for each input.

  1. Input conflicts with row 1, move start time of input to EndDate of row + 3 ms and query (timespan = 6 hours).
  2. Input conflicts with rows 1 & 2, move start time to EndDate of row 1 + 3 ms and end time to StartDate of row 2 - 3 ms. (Timespan = 12 hours)
  3. Input conflicts with row 1, move end time to EndDate of row 1 - 3 ms. (Timepsan = 12 hours).

While this example only shows periods within 1 day, there could be an instance where periods span multiple days.

A: 

To find overlaps, consider that in overlapping rows, both StartDates must occur before either EndDate.

So you should be able to do something like:

select *
from yourTable t1
  join
  yourTable t2
   on  t2.StartDate < t1.EndDate
   and t1.StartDate < t2.EndDate

You may want to make sure that you don't have a row where StartDate > EndDate, using a check constraint. Otherwise, include:

   and t1.StartDate < t1.EndDate
   and t2.StartDate < t2.EndDate
Rob Farley