我希望ind_emp_leaves表中的用户名是相同日期之间的雇主请假,包括日期和日期。
ind_emp_leaves table
username Leavefromdate leavetodate
-------- ------------- ---------
nagarajan 20-JUN-13 21-JUN-13
dhinesh 05-SEP-13 08-SEP-13
raju 08-SEP-13 11-SEP-13
在上表dhinesh和raju假应用于相同的日期(日期之间,一个日期也包括它也被考虑)和nagarajan应用不同的日期,所以我想要dhinesh和raju的用户名。
答案 0 :(得分:1)
您可以使用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
不匹配),其中日期范围并不完全在您正在查看的主行之外。
对于psaraj12;如果你有两个日期范围,它们可以通过多种方式重叠,所以有时候看它们不能这样做会更简单。如果一个范围完全在另一个范围之外,它们不会重叠。也就是说,任何一个范围的'到'日期都在另一个范围的'from'之前。
如果你查看问题的前两行,它们不会重叠,因为'21 -Jun-13&lt; 05年9月5日'是真的。如果比较第二行和第三行,'08 -Sep-13&lt; 08年9月8日'是假的,所以他们确实重叠。
因此iel2.leavetodate < iel.leavefromdate or iel2.leavefromdate > iel.leavetodate
中的逻辑是识别一个范围完全在另一个范围之外的位置,并且这两个范围不重叠。由于我们想知道它们何时发生,因此使用not (...)
来否定整个表达式。
逻辑上这与说where iel2.leavetodate >= iel.leavefromdate and iel2.leavefromdate <= iel.leavetodate
相同,如果这更容易可视化。