从规范化表中选择数据

Selecting Data from Normalized Tables

我一直在尝试编写此查询,我觉得今晚我的脑子有点炸了。我有这个 table 可以在有人执行某项操作(打卡上班、下班打卡、去吃午饭、吃完午饭回来)时存储它,我需要 return 一个包含这些人所有主要 ID 的列表谁的最后一个动作不是 clock_out - 但问题是它需要一个稍微快一点的查询。

Table结构:

ID | person_id | status | datetime | shift_type

ID = 此 table

的主键

person_id = 我想要的 ID return 如果他们的状态不等于 clock_out

状态 = clock_in、lunch_start、lunch_end、break_start、break_end、clock_out

datetime = 添加记录的时间

shift_type = 不重要

我之前执行此查询的方式是查找在特定时间段内仍在打卡的人,但是我需要此查询来定位任何时间点。我正在尝试的查询正在获取成千上万条记录并且速度太慢了。

I need to return a list of all the primary ID's for the people whose last action is not clock_out.

一个选项使用 window 函数,在 MySQL 8.0 中可用:

select id
from (
    select t.*, row_number() over(partition by person_id order by datetime desc) rn
    from mytable t
) t
where rn = 1 and status <> 'clock_out'

在早期版本中,一个选项使用相关子查询:

select id
from mytable 
where 
    datetime = (select max(t1.datetime) from mytable t1 where t1.personid = t.person_id)
    and status <> 'clock_out'

进一步查看后,这是我的解决方案 -

SELECT * FROM (
   SELECT `status`,`person_id` FROM `timeclock` ORDER BY `datetime` DESC
) AS tmp_table GROUP BY `person_id`

之所以可行,是因为它将所有同一个人 ID 组合在一起,然后按日期时间对它们进行排序并选择最新的 ID。