Sql 慢速MS访问子查询

Sql 慢速MS访问子查询,sql,ms-access,subquery,Sql,Ms Access,Subquery,我在Access中有三个表: employees ---------------------------------- id (pk),name times ---------------------- id (pk),employee_id,event_time time_notes ---------------------- id (pk),time_id,note 我想从times表中获取每个员工记录的记录,该记录在某个时间之前有一个事件时间。这样做非常简单: select

我在Access中有三个表:

employees
----------------------------------
id (pk),name

times
----------------------
id (pk),employee_id,event_time

time_notes
----------------------
id (pk),time_id,note
我想从times表中获取每个员工记录的记录,该记录在某个时间之前有一个事件时间。这样做非常简单:

    select employees.id, employees.name, 
(select top 1 times.id from times where times.employee_id=employees.id and times.event_time<=#2018-01-30 14:21:48# ORDER BY times.event_time DESC) as time_id 
from employees
但是,我还想知道time_notes表中是否有匹配的记录:

select employees.id, employees.name, 
(select top 1 time_notes.id from time_notes where time_notes.time_id=(select top 1 times.id from times where times.employee_id=employees.id and times.event_time<=#2018-01-30 14:21:48# ORDER BY times.event_time DESC)) as time_note_present,
(select top 1 times.id from times where times.employee_id=employees.id and times.event_time<=#2018-01-30 14:21:48# ORDER BY times.event_time DESC) as last_time_id 
from employees
这确实管用,但速度太慢了。如果employee表中有100条记录,我们说的是10秒或更长时间。这个问题是Access特有的,因为我不能像在MySQL或SQL Server中那样使用其他子查询的最后一次id结果


我正在寻找如何加快这一进程的技巧。或者是一个不同的查询,或者是索引。有些东西。

不确定这样的东西是否适合你

SELECT 
    employees.id, 
    employees.name, 
    time_notes.id AS time_note_present,
    times.id AS last_time_id
FROM 
    (
        employees LEFT JOIN 
        (
            times INNER JOIN
            (
                SELECT times.employee_id AS lt_employee_id, max(times.event_time) AS lt_event_time
                FROM times
                WHERE times.event_time <= #2018-01-30 14:21:48#
                GROUP BY times.employee_id
            )  
            AS last_times 
            ON times.event_time = last_times.lt_event_time AND times.employee_id = last_times.lt_employee_id
        ) 
        ON employees.id = times.employee_id
    )
    LEFT JOIN time_notes ON times.id = time_notes.time_id;

基本上,您的查询运行多个相关的子查询,甚至是WHERE子句中的嵌套子查询。相关查询分别为每一行计算一个值,对应于外部查询

与@LeeMac类似,只需将所有表连接到按员工id分组的最大事件时间的聚合查询,该查询将在所有行上运行一次。以下时间是连接到聚合查询、员工和时间注释表的baseFROM表:


这个问题可能更适合表达谢意。我是把它也贴上去还是可以移动?你的SQL功夫比我的好。我知道你想做什么,但Access没有。它用不支持的相当无用的联接表达式进行响应。@nemmy,发布后不久我更新了代码-您尝试过更新的版本吗?好奇的OP,@nemmy,您尝试过上面的查询吗?有错误吗?
select e.id, e.name, t.event_time, n.note
from ((times t
inner join 
   (select sub.employee_id, max(sub.event_time) as max_event_time
    from times sub
    where sub.event_time <= #2018-01-30 14:21:48#
    group by sub.employee_id
   ) as agg_qry
on t.employee_id = agg_qry.employee_id and t.event_time = agg_qry.max_event_time)

inner join employees e
on e.id = t.employee_id)

left join time_notes n
on n.time_id = t.id