我需要检索当天的员工在场状态。现场有两种状态: In&退出。 如果员工没有在场,则应检索状态为null。
我有两个表,Employees
和Presences
,我想加入它们。
ID | name
1 John
2 Julie
3 Anthony
4 Joseph
现在,presences表包含以下数据:
ID | employee_id | presence_date | presence_hour | Movement
1 1 2016-08-30 08:55 In
2 2 2016-08-30 08:56 In
3 3 2016-08-30 08:57 In
4 1 2016-08-30 12:33 Out
5 2 2016-08-30 12:34 Out
正如您在在线数据中看到的那样,员工Anthony
尚未离开办公室,而员工Joseph
在表格中没有条目。
我期待的结果:
Employee | Movement
John Out
Julie Out
Anthony In
Joseph null
查询我使用:
SELECT employee.name, presence.movement
FROM employees AS employee
LEFT JOIN presences AS presence ON presence.employee_id = employee.id
WHERE presence.presence_date = '2016-08-30' AND
employee.id IN (1, 2, 3, 4)
GROUP BY employee.id
ORDER BY employee.name, presence.id DESC
我遇到的问题:
presence.id DESC
无法正常工作答案 0 :(得分:2)
对于约瑟夫presence.presence_date
是null
,因此它与presence.presence_date = '2016-08-30'
不匹配。
order by presence.id
对我毫无意义。您按员工进行分组,因此该员工presence
中的所有匹配行都合并在一起。您想根据presence.id
对所有这些进行排序,并选择最新的行movement
值吗?这不会像你写的那样起作用。一种解决方案是在查询中使用MAX(presence.id)
来获取当前员工的最新presence
行的ID,然后再次加入presence
表 获取您想要的数据。
SELECT a.name, b.movement
FROM (
SELECT employee.name, MAX(presence.id) max_id
FROM employees AS employee
LEFT JOIN presences AS presence
ON presence.employee_id = employee.id WHERE presence.presence_date = '2016-08-30' AND
employee.id IN (1, 2, 3, 4)
GROUP BY employee.id
) a
LEFT JOIN presence b ON a.max_id = b.id
ORDER BY a.name
虽然假设most recent
等同于biggest id
可能不是一个好主意,但是可以选择具有最新日期的行,但这是另一个"问题&# 34。
答案 1 :(得分:1)
这是因为在where条件中应用日期过滤器。在>强加入之后应用where条件,从而消除了Joseph的任何记录,因为他当天不在场。请将日期条件移至连接条件。
你得到了整个group by
错误,你的查询是针对sql标准的,因为你在选择列表中的列不在group by list中,并且不是聚合函数的主题,例如为max()
。 MySQL仅允许在某些sql模式设置下进行此类查询。在运动上使用max()
,在员工姓名和日期字段上使用分组。
示例查询,假设您每个员工每天只能有1个输入和1个输出:
SELECT employee.name, max(presence.movement) as movement
FROM employees AS employee
LEFT JOIN presences AS presence ON presence.employee_id = employee.id and date(presence.presence_date) = '2016-08-30'
WHERE employee.id IN (1, 2, 3, 4)
GROUP BY employee.name, date(presence.presence_date)