Php 我们如何将员工的职责随机化
我正试着允许三班倒 存在以下约束:Php 我们如何将员工的职责随机化,php,mysql,Php,Mysql,我正试着允许三班倒 存在以下约束: 1st shift will have 5 employee >2nd shift will have 3 employee 3rd shift will have 2 employee 如果一个人在任何班次中被分配了工作,他将不被允许再工作两个班次。例如,如果X先生在8月3日的第二班被分配了工作,那么他既不会在8月3日的第三班也不会在8月4日的第一班中得到工作 我已经使用rand函数随机选择了员工。我面临约束4的问题。i、 e.我如何确保在第一班
1st shift will have 5 employee
>2nd shift will have 3 employee
3rd shift will have 2 employee
如果一个人在任何班次中被分配了工作,他将不被允许再工作两个班次。例如,如果X先生在8月3日的第二班被分配了工作,那么他既不会在8月3日的第三班也不会在8月4日的第一班中得到工作
我已经使用rand函数随机选择了员工。我面临约束4的问题。i、 e.我如何确保在第一班被分配的员工不会在第二班或第三班被分配
我的MySQL查询是:
SELECT * FROM `employee` ORDER BY rand()
因为您没有提供太多的细节,所以很难弄清楚如何在数据库中存储信息。我想以下问题将适合您的情况:
SELECT * FROM employee e
WHERE e.employee_id NOT IN (
SELECT es.employee_id FROM emp_shifts es
WHERE shift IN (...)
)
ORDER BY RAND()
我假设您正在emp_班次表中存储班次分配。
... 是您要排除的最后两个班次。我认为这是一个很难用SQL解决的问题,但如果我要尝试,我可能会从随机分配员工开始
DROP TABLE IF EXISTS employees;
CREATE TABLE employees
(employee_id SERIAL PRIMARY KEY);
INSERT INTO employees VALUES
(101),(102),(103),(104),(105),(106),(107),(108),(109),(110);
SELECT employee_id,@i:=@i+1 i FROM (SELECT employee_id FROM employees ORDER BY RAND()) x,(SELECT @i:=0) vars;
+-------------+------+
| employee_id | i |
+-------------+------+
| 108 | 1 |
| 109 | 2 |
| 110 | 3 |
| 103 | 4 |
| 105 | 5 |
| 106 | 6 |
| 102 | 7 |
| 104 | 8 |
| 107 | 9 |
| 101 | 10 |
+-------------+------+
现在,只要我们有至少3天的员工5+3+2=10,我们就可以循环浏览列表,并且知道每个员工在每个工作日之间都会有至少两个连续的休息日
下面是关于这个问题的另一个方面的想法
DROP TABLE IF EXISTS shifts;
CREATE TABLE shifts
(shift_id SERIAL PRIMARY KEY
,shift_size INT NOT NULL
);
INSERT INTO shifts VALUES
(1,5),(2,3),(3,2),(4,3),(5,2);
SELECT shift_id
, ROUND(COALESCE(@j:=@prev+1,1),0) range_start
, range_end, @prev:=range_end
FROM
( SELECT x.*
, SUM(y.shift_size) range_end
FROM shifts x
JOIN shifts y
ON y.shift_id <= x.shift_id
GROUP
BY x.shift_id
) b
, ( SELECT @j:=1,@prev:=null) vars
ORDER
BY shift_id;
+----------+-------------+-----------+------------------+
| shift_id | range_start | range_end | @prev:=range_end |
+----------+-------------+-----------+------------------+
| 1 | 1 | 5 | 5 |
| 2 | 6 | 8 | 8 |
| 3 | 9 | 10 | 10 |
| 4 | 11 | 13 | 13 |
| 5 | 14 | 15 | 15 |
+----------+-------------+-----------+------------------+
现在你有了一个雇员序列id和一个范围,这些id可以在这个范围内。范围大于员工列表,因此必须使用员工表的大小作为范围的模数
SELECT a.shift_id
, MOD(a.range_start-1,(SELECT COUNT(*) FROM employees))+1 range_start
, MOD(a.range_end-1,(SELECT COUNT(*) FROM employees))+1 range_end
FROM
( SELECT shift_id
, ROUND(COALESCE(@j:=@prev+1,1),0) range_start
, range_end, @prev:=range_end
FROM
( SELECT x.*
, SUM(y.shift_size) range_end
FROM shifts x
JOIN shifts y
ON y.shift_id <= x.shift_id
GROUP
BY x.shift_id
) b
, ( SELECT @j:=1,@prev:=null) vars
ORDER
BY shift_id
) a
ORDER BY shift_id;
+----------+-------------+-----------+
| shift_id | range_start | range_end |
+----------+-------------+-----------+
| 1 | 1 | 5 |
| 2 | 6 | 8 |
| 3 | 9 | 10 |
| 4 | 1 | 3 |
| 5 | 4 | 5 |
+----------+-------------+-----------+
我想我可以把最后一步留给读者作为练习。尝试使用php并与usSee分享您是如何存储轮班分配详细信息的?请提供SQLFIDLE,以便我提供更好的解决方案。