MySQL检索员工在场

时间:2016-08-31 09:39:42

标签: mysql

我需要检索当天的员工在场状态。现场有两种状态: In&退出。 如果员工没有在场,则应检索状态为null。

我有两个表,EmployeesPresences,我想加入它们。

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

我遇到的问题

  1. 约瑟夫永远不会出现在数据中
  2. presence.id DESC无法正常工作

2 个答案:

答案 0 :(得分:2)

对于约瑟夫presence.presence_datenull,因此它与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)

  1. 这是因为在where条件中应用日期过滤器。在强加入之后应用where条件,从而消除了Joseph的任何记录,因为他当天不在场。请将日期条件移至连接条件。

  2. 你得到了整个group by错误,你的查询是针对sql标准的,因为你在选择列表中的列不在group by list中,并且不是聚合函数的主题,例如为max()。 MySQL仅允许在某些sql模式设置下进行此类查询。在运动上使用max(),在员工姓名和日期字段上使用分组。

  3. 示例查询,假设您每个员工每天只能有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)