MySQL查询以查找事件之间的空闲时间间隔

时间:2018-09-05 18:55:47

标签: mysql

我正在开发用PHP和MySQL开发的约会系统。我目前无法使空闲时间查询正常工作。

我有两个表:

-- Table: works
CREATE TABLE works (
    id int  NOT NULL,
    department_id int  NOT NULL,
    worker_id int  NOT NULL,
    worker_type int  NOT NULL,
    time_start datetime  NOT NULL,
    time_end datetime  NOT NULL,
    CONSTRAINT works_pk PRIMARY KEY (id)
);

-- Table: free_times
CREATE TABLE free_times (
    id int  NOT NULL,
    department_id int  NOT NULL,
    worker_id int  NOT NULL,
    worker_type int  NOT NULL,
    start_dt datetime  NOT NULL,
    end_dt datetime  NOT NULL,
    duration int  NOT NULL,
    CONSTRAINT free_times_pk PRIMARY KEY (id)
);

我需要查询以获取表works中作品之间的空闲时间跨度并将它们存储在表free_times中。时间跨度应以分钟为单位。

我现在正在使用的查询如下:

SELECT e1.department_id, e1.worker_type, e1.worker_id,
e1.time_end as free_time_start,
e2.time_start as free_time_end,
MIN(TIMESTAMPDIFF(MINUTE, e1.time_end, e2.time_start)) as duration
FROM works e1
JOIN works e2
ON e1.department_id=e2.department_id
AND e1.worker_type=e2.worker_type
AND e1.worker_id=e2.worker_id
AND e1.time_end <= e2.time_start
WHERE e1.department_id=? AND e1.worker_id=? AND e1.worker_type=?
AND ((e1.time_end >= '2018-09-06 08:00:00' AND e2.time_start <= '2018-09-06 17:00:00'))
GROUP BY e1.worker_id, e2.time_end

现在,要使此查询正常工作,我需要在运行查询之前将虚拟作品插入works表中。这些假人作品就像是一天的限制器。我在工作日开始时使用time_starttime_end 2018-09-06 08:00添加了一部作品,并在工作日结束时使用了time_starttime_end {{ 1}}

让我们尝试使用此虚拟数据(添加日期分隔符):

2018-09-06 17:00

运行空闲时间查询会给我结果:

“ free_time_start”:“ 2018-09-06 08:00:00 ”,“ free_time_end”:“ 2018-09-06 08:00:00 ” ,“ duration”:“ 0”
“ free_time_start”:“ 2018-09-06 08:00:00 ”,“ free_time_end”:“ 2018-09-06 09:30:00 ”,“持续时间“:” 90“
“ free_time_start”:“ 2018-09-06 10:30:00 ”,“ free_time_end”:“ 2018-09-06 11:00:00 ”,“持续时间“:” 30“
“ free_time_start”:“ 2018-09-06 17:00:00 ”,“ free_time_end”:“ 2018-09-06 17:00:00 ”,“持续时间“:” 0“

以某种方式,我错过了从 13:00 17:00 的时间范围,我真的无法自己弄清楚。欢迎任何建议使此查询正常工作。

我需要做的就是获取查询以查找空闲时间跨度,存储结果并插入和删除开始和结束日期分隔符。

编辑:MySql版本为5.1.72

1 个答案:

答案 0 :(得分:0)

我认为您需要同时获取e1和e2的开始结束结束时间,并且仅在e2.time_end与e1.time_start不同时才加入:

SELECT e1.department_id, e1.worker_type, e1.worker_id,
e1.time_start as work1_start,
e1.time_end as work1_end,
e2.time_start as work2_start,
e2.time_end as work2_end,
MIN(TIMESTAMPDIFF(MINUTE, e1.time_end, e2.time_start)) as duration
FROM works e1
JOIN works e2
ON e1.department_id=e2.department_id
AND e1.time_end <= e2.time_start
AND e2.time_end <> e1.time_start
WHERE e1.department_id=1 AND e1.worker_id=15 AND e1.worker_type=1
AND ((e1.time_end >= '2018-09-06 08:00:00' AND e2.time_start <= '2018-09-06 17:00:00'))
GROUP BY e1.worker_id, e1.time_start

输出:

work1_start             work1_end               work2_start             work2_end               duration
2018-09-06 08:00:00     2018-09-06 08:00:00     2018-09-06 09:30:00     2018-09-06 10:30:00     90
2018-09-06 09:30:00     2018-09-06 10:30:00     2018-09-06 17:00:00     2018-09-06 17:00:00     30
2018-09-06 11:00:00     2018-09-06 13:00:00     2018-09-06 17:00:00     2018-09-06 17:00:00     240

更新:

添加了新行INSERT INTO工作( id ,部门ID , worker_id , worker_type , time_start , time_end { {1}}

重新订购ID为:

) VALUES
(5, 1, 15, 1, '2018-09-06 14:00:00', '2018-09-06 15:00:00');

重新运行查询:

1   1   15  1   2018-09-06 08:00:00 2018-09-06 08:00:00
2   1   15  1   2018-09-06 09:30:00 2018-09-06 10:30:00
3   1   15  1   2018-09-06 11:00:00 2018-09-06 13:00:00
4   1   15  1   2018-09-06 14:00:00 2018-09-06 15:00:00
5   1   15  1   2018-09-06 17:00:00 2018-09-06 17:00:00