data67 has asked for the wisdom of the Perl Monks concerning the following question:

HI all, I have been trying to figuare out a way to fix a problem that i have been having in my perl code. The issue is that i have to make a call to the table and check for the existance of overlapping dates before i insert a row in my table.

I know some people will suggest "Date::Calc" etc but i wanted to somehow just do this check in my sql call and save time (instead of reading each row and running a date::calc on it). how can i do this? is there a simpler way to do a range check? (maybe with SQL and/or/between? I think between wont work because i have to check 2 dates against 2 params in my program? i donno?)

I want to check that there is no overlapping row in the table where the effective date & expiration date overlap. think of this like a scheduling system where i cant book an appointment over another. here is what my table look like:

Table: Company_relationship company_number relationship_type effective_date expiration_date

Replies are listed 'Best First'.
Re: Overlapping dates Issue
by ikegami (Patriarch) on Mar 20, 2006 at 22:43 UTC

    If there is no range (just single dates), that's easy. Just count the rows:

    SELECT COUNT(*) FROM Company_relationship WHERE effective_date = ? OR expiration_date = ?

    If effective_date and expiration_date are begin and end dates, I bet you can do:

    SELECT COUNT(*) FROM Company_relationship WHERE effective_date <= ? AND expiration_date > ?

    Both return one record with one field. If it's 0, proceed. Otherwise, you have an overlap.

      Actually, yes there is a concept here of overlapping. I used your query and it did not work for all cases. I went on Oracles website and found the answer there. Here is the link:

      http://asktom.oracle.com/pls/ask/f?p=4950:8:15236886734525876868::NO::F4950_P8_DISPLAYID,F4950_P8_CRITERIA:4921012347969,

      and we said... Do you need to be concerned with all overlaps? Eg: in database you have

      01-jan-2001 07-jan-2001

      you are given as inputs:

      15-dec-2000 15-jan-2001 - wider then database 15-dec-2000 04-jan-2001 - overlaps but not contained within 04-jan-2001 15-jan-2001 - overlaps but not contained within 02-jan-2001 04-jan-2001 - overlaps and contained within

      should all four return a "hit"?

      select * from t where ( c_beginning between p_beginning and p_ending -- rule 1 OR c_ending between p_beginning and p_ending -- rule 2 OR ( c_beginning < p_beginning and p_ending < c_ending ) ); -- + rule 3
      will do that. If you use the following "chart", it depicts all of the possibles and which "rule" in the predicate above will catch them:
      ............................................. CB CE PB PE -- rule 1 PB PE -- rule 1 PB PE -- rule 2 PB PE -- rule 3 PB PE -- no hit PB PE -- no hit

      Thanks,
      data