SQL在可用性之外进行转换

时间:2015-03-04 04:50:37

标签: mysql sql

我试图整理一个sql查询来获取超出其调度应用程序可用性的员工轮班。可用性条目将是连续的,并且永远不会具有为同一雇员背靠背的可用性条目,也不会存在对同一雇员重叠的可用性条目。

基本上,我需要得到(availabilities.start <= shifts.start AND availabilities.end >= shifts.end)不成立的移位行。换句话说,我需要从轮换表中获取未被可用性条目完全包含的行。

需要考虑这些可能性:

  • 在可用性之前开始的转移
  • 在可用性之后移动
  • 班次期间没有任何可用性的班次

如果这样做效率更高,我可以使用存储过程而不是查询。

这是表格的样子:

CREATE TABLE availabilities (`id` int primary key, `employee_id` int, `start` datetime, `end` datetime);
CREATE TABLE shifts (`id` int primary key, `employee_id` int, `start` datetime, `end` datetime);

以下是一些示例数据:

INSERT INTO availabilities
    (`employee_id`, `start`, `end`)
VALUES
    (1, '2015-01-01 08:00:00', '2015-01-01 09:00:00'),
    (1, '2015-01-02 08:00:00', '2015-01-02 10:00:00'),
    (2, '2015-01-03 08:00:00', '2015-01-03 14:00:00'),
    (2, '2015-01-04 08:00:00', '2015-01-04 18:00:00')
;

INSERT INTO shifts
    (`employee_id`, `start`, `end`)
VALUES
    (1, '2015-01-01 08:00:00', '2015-01-01 09:00:00'),
    (1, '2015-01-02 08:30:00', '2015-01-02 10:00:00'),
    (1, '2015-01-02 10:30:00', '2015-01-02 12:00:00'),
    (2, '2015-01-03 08:00:00', '2015-01-03 09:00:00'),
    (2, '2015-01-03 09:00:00', '2015-01-03 14:30:00'),
    (2, '2015-01-04 09:30:00', '2015-01-04 17:30:00'),
    (2, '2015-01-05 08:00:00', '2015-01-05 10:00:00')
;

我希望第3班,第5班和第7班可以输出,因为它们超出了可用性。

我已经尝试了类似下面的内容(以及其他许多内容),但是所有这些都会给出误报或遗漏轮班。

SELECT s.*  FROM `shifts` AS `s`
LEFT JOIN `availabilities` AS `a` ON `s`.`employee_id` = `a`.`employee_id`
WHERE (NOT(a.start <= s.start AND a.end >= s.end) OR a.id IS NULL);

1 个答案:

答案 0 :(得分:0)

这有帮助吗?

select *
from shifts as s
where not exists (
    select 1
    from availabilities as a
    where a.start <= s.start AND a.end >= s.end and a.employee_id = s.employee_id
)