I\'ve a simple table in sql server 2005 with 3 columns: DateStart, DateEnd and Value. I tried to set a \"table check constraint\" to avoid inserting overlapping records. For
The CHECK is being executed after the row has been inserted, so the range overlaps with itself.
You'll need to amend your WHERE to include something like: @MyTableId <> MyTableId
.
BTW, your WHERE expression can be simplified.
Ranges don't overlap if:
Which could be written in SQL like:
WHERE @DateEnd < DateStart OR DateEnd < @DateStart
Negate that to get the ranges that do overlap...
WHERE NOT (@DateEnd < DateStart OR DateEnd < @DateStart)
...which according to De Morgan's laws is the same as...
WHERE NOT (@DateEnd < DateStart) AND NOT (DateEnd < @DateStart)
...which is the same as:
WHERE @DateEnd >= DateStart AND DateEnd >= @DateStart
So your final WHERE should be:
WHERE
@MyTableId <> MyTableId
AND @DateEnd >= DateStart
AND DateEnd >= @DateStart
[SQL Fiddle]
NOTE: to allow ranges to "touch", use <=
in the starting expression, which would produce >
in the final expression.
I'd just like to add onto the Answer of Branko Dimitrijevic the case where the DateEnd is null since I currently have such a scenario.
This can occur when you're keeping punch in logs and the user is still logged in.
WHERE
@MyTableId <> MyTableId
AND @DateEnd >= DateStart
AND DateEnd >= @DateStart
OR @DateEnd >= DateStart
AND DateEnd is null
OR @DateStart >= DateStart
AND DateEnd is null
I don't know how well this query is performance wise, I'm sure there are ways to optimize it.