我在运输公司的申请表中包含以下字段的表格......
jempe_users
+------------------------------+
| Field |
+------------------------------+
| user_id |
| user_user_group_id |
| user_type |
| user_real_name |
| user_drv_code |
+------------------------------+
jempe_user_types:
+---------------------+
| Field |
+---------------------+
| user_type_id |
| user_type_name |
+---------------------+
employee_clock_events:
+-----------------------+
| Field |
+-----------------------+
| ece_id |
| ece_employee_id |
| ece_type |
| ece_datetime |
| ece_active |
+-----------------------+
我需要做的是建议三个目前正在工作而不是休息的司机,这些司机可以被分配来接送病人。
jempe_users表包含员工以及运输公司的一些客户。用户类型表有一条记录,其中user_type_name = driver和jempe_users表中的user_type字段引用了jempe_user_types表。
employee_clock_events表用于在轮班期间为员工提供进出时间。 ece_type字段是枚举('shift_start','shift_brake','shift_resume','shift_stop')。 ece_datetime字段存储转移事件发生的时间点。
所以我需要做的是在user_group 16,17或18中查找当前正在工作的驱动程序用户类型以及最近的移位ece_type是'shift_start'还是'shift_resume'。
我已经尝试了以下几十种变体,但似乎无法选择目前正在工作的员工。我似乎没有选择今天至少工作过的员工的问题。
尝试过这种变化...
SELECT user_id, driver_name, driver_code
FROM
(
SELECT
u.user_id AS user_id,
u.user_real_name AS driver_name,
u.user_drv_code AS driver_code,
e.ece_type AS event_type,
e.ece_datetime AS event_datetime
FROM employee_clock_events AS e
INNER JOIN jempe_users AS u
ON e.ece_employee_id = u.user_id
LEFT JOIN jempe_user_types AS ut
ON u.user_type = ut.user_type_id
WHERE
e.ece_shift_date = '2011-09-13'
AND ut.user_type_name = 'driver'
AND u.user_user_group_id IN (16, 17, 18)
AND NOT ISNULL(u.user_drv_code)
AND u.user_active = 1
) AS TEMPORARY
GROUP BY user_id
HAVING MAX(event_datetime)
这就是......
SELECT u.user_id AS user_id, u.user_real_name AS driver_name, u.user_drv_code AS driver_code, MAX(e.ece_datetime) AS current_event_datetime
FROM employee_clock_events AS e
LEFT JOIN jempe_users AS u
ON e.ece_employee_id = u.user_id
LEFT JOIN jempe_user_types AS ut
ON u.user_type = ut.user_type_id
WHERE
(e.ece_type = 'shift_start' OR e.ece_type = 'shift_resume')
AND e.ece_shift_date = '2011-09-13'
AND ut.user_type_name = 'driver'
AND u.user_user_group_id IN (16, 17, 18)
AND NOT ISNULL(u.user_drv_code)
AND u.user_active = 1
GROUP BY e.ece_employee_id
我哪里错了?谢谢你的帮助。
答案 0 :(得分:2)
您的问题是确定每位员工最近的时钟事件。这部分问题可以解决如下:
CREATE VIEW MRClockByEmployee (ece_employee_ID, ece_most_recent_datetime) AS
AS SELECT ece_employee_ID, MAX(ece_datetime)
FROM employee_clock_events
GROUP BY ece_employee_id;
CREATE VIEW MRClockInfoByEmployee
(ece_id, ece_employee_ID, ece_type, ece_datetime, ece_active) AS
SELECT CE.* FROM employee_clock_events CE JOIN MRClockByEmployee MR
ON CE.ece_employee_ID = MR.ece_employee_id AND
CE.ece_datetime = MR.ece_most_recent_datetime
SELECT ece_employee_id FROM MRClockInfoByEmployee
WHERE type IN ('shift_start', 'shift_resume')
然后,您可以将第二个视图的内容加入到其他表中以获取其他信息,并为您的三个可能的驱动程序获取TOP 3记录。
请注意,您可以在一个更复杂的查询中完成所有这些操作,但我认为“员工当前状态”的概念非常重要且足够可重用,因此值得在视图中封装逻辑。
最终解决方案(将表连接在一起)不会使用GROUP BY。这是因为必须在解决方案算法中相对较早地使用GROUP BY才能创建员工ID列表和最近的日期时间值;然后将该列表连接回employee表,以获取该表中最新记录的列表。
答案 1 :(得分:0)
我需要进一步测试,但我最终还是继续这个......
SELECT u.user_id, u.user_real_name AS driver_name, u.user_drv_code AS driver_code
FROM
(
SELECT ece_employee_id, MAX(ece_datetime) AS ece_datetime
FROM employee_clock_events
WHERE ece_active = 1 AND ece_shift_date = '2011-09-13'
GROUP BY ece_employee_id
) AS mre
INNER JOIN employee_clock_events AS e
ON e.ece_employee_id = mre.ece_employee_id AND e.ece_datetime = mre.ece_datetime
LEFT JOIN jempe_users AS u
ON e.ece_employee_id = u.user_id
LEFT JOIN jempe_user_types AS ut
ON u.user_type = ut.user_type_id
WHERE
(e.ece_type = 'shift_start' OR e.ece_type = 'shift_resume')
AND e.ece_shift_date = '2011-09-13'
AND ut.user_type_name = 'driver'
AND u.user_user_group_id IN (16, 17, 18)
AND NOT ISNULL(u.user_drv_code)
AND u.user_active = 1
到目前为止似乎工作正常。我还没有能够得到拉里的观点建议,但我会稍后再查看。如果它似乎有用,我会将他的答案标记为正确。有没有人看到这个有什么问题?