如何使用两个不同的日期列在相同日期之间获取数据

时间:2013-09-05 06:17:59

标签: oracle oracle11g

我希望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的用户名。

1 个答案:

答案 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不匹配),其中日期范围并不完全在您正在查看的主行之外。

SQL Fiddle


对于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相同,如果这更容易可视化。