0

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

4

1 回答 1

1

You can look for rows that have overlapping dates using an exists clause:

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   

Or if you want to know about the overlap, not just that it exists, you can use an outer join:

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       

In both cases, the join is looking for different rows (because rowid doesn't match), where the date range is not entirely outside the main row you're looking at.

SQL Fiddle.


For psaraj12; if you have two date ranges, there are a number of ways they can overlap, so it's simpler sometimes to look at when they cannot do so. They do not overlap if one range is completely outside the other. That is, the 'to' date of either range is before the 'from' date of the other.

If you look at the first two rows from the question, they do not overlap because '21-Jun-13 < 05-Sep-13' is true. If you compare the second and third rows, '08-Sep-13 < 08-Sep-13' is false, so they do overlap.

So the logic in iel2.leavetodate < iel.leavefromdate or iel2.leavefromdate > iel.leavetodate is identifying where one range is completely outside the other, and the two ranges do not overlap. Since we want to know when they do, the whole expression is negated with the not (...).

Logically this is the same as saying where iel2.leavetodate >= iel.leavefromdate and iel2.leavefromdate <= iel.leavetodate, if that's easier to visualise.

于 2013-09-05T08:45:47.690 回答