【发布时间】:2016-07-15 03:18:46
【问题描述】:
我有一个存储员工轮班记录的表。
简单来说就是以下数据:
id = Shift ID
employeenum = Employee Number
start = unix timestamp of shift start time
end = unix timestamp of shift end time
date = YYYY-mm-dd description of date the shift starts on
status = shift status (numeric status identifier)
我目前正在通过循环 php 脚本确定冲突,但它太慢了。我搜索了其他问题,但找不到我正在寻找的答案。
我正在尝试提出一个查询,该查询基本上会给我一个在给定时间段内具有冲突轮班的员工编号列表。
即在 2016 年 7 月 3 日至 2016 年 7 月 10 日期间,哪些员工的轮班开始和结束时间戳重叠,状态值为 1 或 7。
任何帮助将不胜感激。
谢谢!
编辑
This本质上是表结构。
id 是一个主要的自动增量键。该表充满了数字数据。
ID 是一个自动递增的数字,employeenum 是一个 6 位数字,开始和结束是 unix 时间戳,日期是 YYYY-mm-dd 日期格式,覆盖是 1 或 0,状态是 1,2,3,4,5 ,6 或 7。
当前循环通过查询来工作:
SELECT * FROM schedule WHERE overridden =0 AND date >=$startdate AND date <= $enddate AND (status = 1 OR status = 7) AND employeenum != 0 ORDER BY date ASC
然后循环遍历所有返回的班次,通过反复执行此查询(使用上述查询结果中返回的start 和end 值)来测试另一个班次是否与它们发生冲突:
SELECT `employeenum` FROM `schedule` WHERE `overridden` =0 AND `date` >= '$startdate' AND `date` <= '$enddate' AND (`status` = '1' OR `status` = '7') AND ((('$start' > `start`) AND ('$start' < `end`)) OR ((`end` > '$start') AND (`end` < '$end'))) AND `employeenum` = '$employee';"
如果有结果,它将员工编号推送到有冲突的员工数组中。这样可以防止循环再次检查该员工。
在任何给定时间都可能有 10,000 条记录,因此它正在执行 10,000 多个查询。这些记录仅代表 100-200 名员工,因此我正在寻找一种方法来查询一次以查看两个 @ 之间是否有任何重叠(start 和 end 与另一个 start 或 end 重叠)记录一个 employeenum 的 987654332@ 值,而无需查询数据库 10,000 次。
【问题讨论】:
-
让我们看看你的 php 代码!
-
基本上它遵循这个逻辑:选择时间段内的记录。循环遍历记录,如果员工编号不在冲突数组中,则检查是否存在冲突。如果存在冲突,将员工编号推送到冲突数组。移至下一条记录。问题是它太慢了,而且每次都一遍又一遍地查询。如果可能的话,我想用一个查询来解决这个问题。
-
抱歉,这里的解释不会删减,请附上您的代码,我们可以提供帮助
-
谢谢你,我很感激你的意图,但是正如我所说,我正在寻找一个查询解决方案,而不是对 PHP 代码的修订。客户端使用的托管包无法进行迭代重复查询,这就是为什么我试图通过每个员工 1 个查询来完成它。我正在寻求构建查询的帮助。
-
好的,你需要包含你的原始查询,你还应该更新你的数据结构,即
id你的主自动增量键 - 或者 - 它是链接到班次的外键表...在此处提供一些示例数据或粘贴内容sqlfiddle.com 并提供链接