doukuang8166 2016-07-11 19:33
浏览 35
已采纳

用于确定重叠时间戳的MySQL查询 - 调度系统

I have a table that stores shift records for employees.

Simply, there's the following data:

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)

I am currently determining conflicts through a looping php script but it's far too slow. I've searched other questions and can't quite find the answer I'm looking for.

I am trying to come up with a query that will basically give me a list of employeenums that have conflicting shifts within a given time period.

i.e. for the period 2016-07-03 to 2016-07-10, which employees have overlapping start and end timestamps for shifts with a status value of 1 or 7.

Any help would be appreciated.

Thank you!

EDIT

This is essentially the table structure.

id is a primary auto increment key. The table is full of numeric data.

ID is an autoincremented number, employeenum is a 6 digit number, start and end are unix timetamps, date is YYYY-mm-dd date format, overridden is 1 or 0, status is 1,2,3,4,5,6, or 7.

Current loop works by querying:

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

It then loops through all of those returned shifts to test whether or not another one conflicts with them by executing this query over and over (using the returned start and end values from the results of the above query):

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';"

If there is a result, it pushes the employee number to an array of employees with conflicts. This then prevents the loop from checking for that employee again.

At any given time there could be 10,000 records, so it's executing 10,000+ queries. These records represent only 100-200 employees, so I am looking for a way to query one time to see if there are any overlapping (start and end overlap with another start or end) records between two date values for one employeenum without having to query the database 10,000 times.

  • 写回答

2条回答 默认 最新

  • dqayok7935 2016-07-14 19:18
    关注

    Adapted from @cmorrissey 's answer. THANK YOU!!

    SELECT `schedule_test`.`id`, `schedule_test`.`date`, 
    `schedule_test`.`employeenum`,     
    GROUP_CONCAT(DISTINCT`join_tbl`.`employeenum`),  
    COUNT(`join_tbl`.`employeenum`)
    
    FROM `schedule_test` 
    INNER JOIN `schedule_test` AS `join_tbl` ON 
    `schedule_test`.`date` = `join_tbl`.`date` 
    AND (`join_tbl`.`status` = 1 OR `join_tbl`.`status` = 7)
    AND (`join_tbl`.`employeenum` = `schedule_test`.`employeenum`) 
    AND (`join_tbl`.`start` BETWEEN `schedule_test`.`start` AND `schedule_test`.`end` 
        OR `join_tbl`.`end` BETWEEN `schedule_test`.`start` AND `schedule_test`.`end`) 
    AND `schedule_test`.`id` != `join_tbl`.`id` 
    WHERE (`schedule_test`.`status` = 1 OR `schedule_test`.`status` = 7) 
    GROUP BY `schedule_test`.`id`
    ORDER BY `schedule_test`.`date`
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 如何实验stm32主通道和互补通道独立输出
  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题