Never been to DZone Snippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

« Newer Snippets
Older Snippets »
Showing 1-1 of 1 total  RSS 

Pull Date-Effective Records that Overlap Each Other

Basic framework and examples of how to pull records that overlap each other from a temporal (aka date-effective) database.

   1  
   2  -- PK is a placeholder for the Primary Key column(s)
   3  -- SoftPK is a placeholder for columns that need to match for overlap, but are not the PK
   4  -- Sometimes SoftPK is the PK, in which case you remove the <> PK line and match the SoftPK.
   5  -- The idea is to check for overlap on all rows except for yourself, since that always overlaps.
   6  --   This snippet assumes the EndDate column has a NULL to represent infinity.
   7  --   There are alternate syntaxes for this (compare or EndDate is null) but I've found
   8  --   the Coalesce to provide the best query plan usually. The constant itself is debatable and
   9  --   implementation dependent.
  10  select outer.*
  11  from DateEffectiveTable as outer
  12  where exists (
  13    select 1
  14    from DateEffectiveTable as inner
  15    where inner.PK <> outer.PK
  16      -- and inner.SoftPK = outer.SoftPK
  17      and inner.StartDate <= coalesce(outer.EndDate, '9999-12-31')
  18      and coalesce(inner.EndDate, '9999-12-31') > outer.StartDate
  19  )
  20  
  21  
  22  -- Example Usage
  23  -- Assume we have a table containing the address history for a person
  24  -- A person may have multiple addresses at once (own multiple houses).
  25  -- A person may move away then back (same address, different time ranges).
  26  -- ie, multiple simultaneous unique records are possible, but not
  27  -- multiple simultaneous non-unique records (no self-overlap).
  28  -- Yes, it is usually an odd design to have an AddressID, but go with it.
  29  select outer.*
  30  from AddressHistory as outer
  31  where exists (
  32    select 1
  33    from AddressHistory as inner
  34    where outer.AddressID <> inner.AddressID
  35      and outer.PersonID = inner.PersonID
  36      and outer.Street = inner.Street
  37      and outer.Zip = inner.Zip
  38      and inner.StartDate <= coalesce(outer.EndDate, '9999-12-31')
  39      and coalesce(inner.EndDate, '9999-12-31') > outer.StartDate
  40  
  41  
  42  -- Same example, but assume PK is a more "appropriate" one of
  43  -- { PersonID, Street, Zip, StartDate }
  44  select outer.*
  45  from AddressHistory as outer
  46  where exists (
  47    select 1
  48    from AddressHistory as inner
  49    where 
  50      not (
  51       outer.PersonID = inner.PersonID
  52       and outer.Street = inner.Street
  53       and outer.Zip = inner.Zip
  54       and outer.StartDate = inner.StartDate
  55      )
  56      and outer.PersonID = inner.PersonID
  57      and outer.Street = inner.Street
  58      and outer.Zip = inner.Zip
  59      and inner.StartDate <= coalesce(outer.EndDate, '9999-12-31')
  60      and coalesce(inner.EndDate, '9999-12-31') > outer.StartDate
« Newer Snippets
Older Snippets »
Showing 1-1 of 1 total  RSS