我的 MySQL 数据库中有一个表,其中包含我的工作人员的日程模板,然后在日程规划器中使用这些模板。当员工的雇佣合同发生修改时,新的时间表会添加一组新的记录。
到目前为止我有以下疑问:
SELECT
ehp.id_pers_empleado employee_id,
ehp.diasem weekday,
ehp.hora_inicio `from`,
ehp.hora_fin `to`,
ehp.validez `starts`,
TIMESTAMPDIFF( MINUTE, ehp.hora_inicio, ehp.hora_fin ) / 60 worked
FROM
empleados_horarios_predeterminados ehp
WHERE
id_pers_empleado = 476
ORDER BY
`starts`,
weekday
该查询返回以下字段:
场 | 类型 | 描述 |
---|---|---|
员工_id | int | 员工ID |
工作日 | int | 1(星期一)至7(星期日) |
来自 | 时间 | 轮班开始时间 |
到 | 时间 | 轮班结束时间 |
开始 | 日期 | 该记录生效的日期 |
小时 | 漂浮 | 员工的工作时间(以节省时间) |
这样我得到的记录如下:
员工_id | 工作日 | 来自 | 到 | 开始 | 工作了 |
---|---|---|---|---|---|
00000476 | 1 | 09:00:00 | 14:00:00 | 2024-04-01 | 5.0000 |
00000476 | 2 | 09:00:00 | 14:00:00 | 2024-04-01 | 5.0000 |
00000476 | 3 | 09:00:00 | 14:00:00 | 2024-04-01 | 5.0000 |
00000476 | 4 | 09:00:00 | 14:00:00 | 2024-04-01 | 5.0000 |
00000476 | 5 | 09:00:00 | 14:00:00 | 2024-04-01 | 5.0000 |
00000476 | 1 | 07:00:00 | 15:30:00 | 2024-05-01 | 8.5000 |
00000476 | 2 | 07:00:00 | 15:00:00 | 2024-05-01 | 8.0000 |
00000476 | 3 | 07:00:00 | 15:00:00 | 2024-05-01 | 8.0000 |
00000476 | 4 | 07:00:00 | 15:00:00 | 2024-05-01 | 8.0000 |
00000476 | 5 | 07:00:00 | 15:00:00 | 2024-05-01 | 8.0000 |
我需要知道员工在特定日期范围内的工作安排。
例如,如果我查询从 4/29/2024 到 5/5/2024 的一周,我期望收到:
即以下一组记录:
员工_id | 日期 | 来自 | 到 | 开始 | 工作了 |
---|---|---|---|---|---|
00000476 | 2024-04-29 | 09:00:00 | 14:00:00 | 2024-04-01 | 5.0000 |
00000476 | 2024-04-30 | 09:00:00 | 14:00:00 | 2024-04-01 | 5.0000 |
00000476 | 2024-05-01 | 07:00:00 | 15:00:00 | 2024-05-01 | 8.0000 |
00000476 | 2024-05-02 | 07:00:00 | 15:00:00 | 2024-05-01 | 8.0000 |
00000476 | 2024-05-03 | 07:00:00 | 15:00:00 | 2024-05-01 | 8.0000 |
通过这些数据,我想知道该员工该周工作了多少小时,或者自动创建未来几周的时间表。
我一整天都在绞尽脑汁试图找到一种方法使其成为可能,但我尝试的一切都没有给出预期的结果。
最后一次尝试是:
SELECT
*
FROM (
SELECT
ehp.id_pers_empleado AS employee_id,
ehp.diasem AS weekday,
ehp.hora_inicio AS `from`,
ehp.hora_fin AS `to`,
ehp.validez AS `starts`,
TIMESTAMPDIFF( MINUTE, ehp.hora_inicio, ehp.hora_fin ) / 60 AS worked,
DATE_ADD( "2024-04-29", INTERVAL diasem - 1 DAY ) effective_day
FROM
empleados_horarios_predeterminados ehp
WHERE
id_pers_empleado = 476
ORDER BY
STARTS,
weekday
) q1
WHERE
effective_day >= q1.`starts`
AND STARTS <= "2024-05-01"
GROUP BY
weekday
这为我一直在谈论的具体案例提供了正确的结果集,但由于其他员工有超过 2 个时间表或在其他日期范围内,因此失败。
您可以使用递归 CTE 创建日期系列和横向派生表以获得正确的时间表:
WITH RECURSIVE date_range (dt) AS (
SELECT '2024-04-29' -- start date
UNION ALL
SELECT dt + INTERVAL 1 DAY FROM date_range WHERE dt < '2024-05-03' -- end date
)
SELECT *
FROM date_range dr
JOIN LATERAL (
SELECT *, (TIME_TO_SEC(hora_fin) - TIME_TO_SEC(hora_inicio)) / 3600 AS worked
FROM empleados_horarios_predeterminados
WHERE id_pers_empleado = 476
AND validez <= dr.dt
AND WEEKDAY(dr.dt) + 1 = diasem
ORDER BY validez DESC
LIMIT 1
) ehp;
这是一个db<>小提琴。