I’m studying Employees Sample Database which has the following table.
create table dept_emp
(
emp_no int not null,
dept_no char(4) not null,
from_date date not null,
to_date date not null,
primary key (emp_no, dept_no),
constraint dept_emp_ibfk_1
foreign key (emp_no) references employees (emp_no)
on delete cascade,
constraint dept_emp_ibfk_2
foreign key (dept_no) references departments (dept_no)
on delete cascade
);
create index dept_no
on dept_emp (dept_no)
And two views are defined which imply that from_date
and to_date
are not overlaps.
create definer = root@localhost view current_dept_emp as
select `employees`.`l`.`emp_no` AS `emp_no`,
`d`.`dept_no` AS `dept_no`,
`employees`.`l`.`from_date` AS `from_date`,
`employees`.`l`.`to_date` AS `to_date`
from (`employees`.`dept_emp` `d` join `employees`.`dept_emp_latest_date` `l`
on (((`d`.`emp_no` = `employees`.`l`.`emp_no`) and (`d`.`from_date` = `employees`.`l`.`from_date`) and
(`employees`.`l`.`to_date` = `d`.`to_date`))));
create definer = root@localhost view dept_emp_latest_date as
select `employees`.`dept_emp`.`emp_no` AS `emp_no`,
max(`employees`.`dept_emp`.`from_date`) AS `from_date`,
max(`employees`.`dept_emp`.`to_date`) AS `to_date`
from `employees`.`dept_emp`
group by `employees`.`dept_emp`.`emp_no`;
Here comes a query and a result.
select *
from dept_emp
where emp_no = 499018
;
emp_no dept_no from_date to_date
------------------------------------
499018 d004 1996-03-25 9999-01-01
499018 d009 1994-08-28 1996-03-25
How can I query the dept_emp
table so that I can confirm, at least in database, and implicitly, that
- at each given
emp_no
- no period(
from_date
andto_date
) doesn’t overlaps
2
Answers
To find overlaps, use the lag window function:
(or
<=
instead of<
if the previous to_date being equal to the from_date is considered an overlap)Use an
EXISTS
clause to see whether there is an overlapping row for some row.We want to check whether for some row there exists another row for the same employee with an overlapping range. We detect that it is another row, by looking at the department, as
the combination of employee ID and department ID is unique in the table. In other words: an employee cannot switch to and fro.
If you consider your example overlapping (i.e. there is no switch day where the employee is in both departments, but it must be different days), then you must change
<
and>
to<=
and>=
in this query.