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 如何在node.js中或者java中给wav格式的音频编码成sil格式呢
  • ¥15 不小心不正规的开发公司导致不给我们y码,
  • ¥15 我的代码无法在vc++中运行呀,错误很多
  • ¥50 求一个win系统下运行的可自动抓取arm64架构deb安装包和其依赖包的软件。
  • ¥60 fail to initialize keyboard hotkeys through kernel.0000000000
  • ¥30 ppOCRLabel导出识别结果失败
  • ¥15 Centos7 / PETGEM
  • ¥15 csmar数据进行spss描述性统计分析
  • ¥15 各位请问平行检验趋势图这样要怎么调整?说标准差差异太大了
  • ¥15 delphi webbrowser组件网页下拉菜单自动选择问题