exists
句を使用して、日付が重複している行を探すことができます。
select * from ind_emp_leaves iel
where exists (
select 1 from ind_emp_leaves iel2
where not (iel2.leavetodate < iel.leavefromdate
or iel2.leavefromdate > iel.leavetodate)
and iel2.rowid != iel.rowid
);
USERNAME LEAVEFROMDATE LEAVETODATE
---------- ------------- -----------
dhinesh 05-SEP-13 08-SEP-13
raju 08-SEP-13 11-SEP-13
または、オーバーラップが存在するだけでなく、オーバーラップについて知りたい場合は、外部結合を使用できます。
select iel.username, iel.leavefromdate, iel.leavetodate,
iel2.username as overlaps
from ind_emp_leaves iel
left join ind_emp_leaves iel2
on not (iel2.leavetodate < iel.leavefromdate
or iel2.leavefromdate > iel.leavetodate)
and iel2.rowid != iel.rowid
where iel2.username is not null;
USERNAME LEAVEFROMDATE LEAVETODATE OVERLAPS
---------- ------------- ----------- ----------
raju 08-SEP-13 11-SEP-13 dhinesh
dhinesh 05-SEP-13 08-SEP-13 raju
どちらの場合も、結合は異なる行を探しています (rowid
一致しないため)。日付範囲は、見ているメインの行から完全には外れていません。
SQLフィドル。
psaraj12 の場合。2 つの日付範囲がある場合、重複する方法がいくつかあるため、重複できない場合を確認する方が簡単な場合があります。一方の範囲がもう一方の範囲の完全に外側にある場合、それらは重複しません。つまり、いずれかの範囲の「終了日」が、他方の「開始日」よりも前になっています。
質問の最初の 2 行を見ると、'21-Jun-13 < 05-Sep-13' が true であるため、重複していません。2 番目と 3 番目の行を比較すると、'08-Sep-13 < 08-Sep-13' は偽であるため、重複しています。
したがって、ロジックiel2.leavetodate < iel.leavefromdate or iel2.leavefromdate > iel.leavetodate
は、一方の範囲がもう一方の範囲から完全に外れており、2 つの範囲が重複していない場所を特定します。それらがいつ実行されるかを知りたいので、式全体が . で否定されnot (...)
ます。
where iel2.leavetodate >= iel.leavefromdate and iel2.leavefromdate <= iel.leavetodate
論理的には、視覚化する方が簡単であれば、これは と言うのと同じです。