我在Access中有三个表:
employees
----------------------------------
id (pk),name
times
----------------------
id (pk),employee_id,event_time
time_notes
----------------------
id (pk),time_id,note
我希望在一段时间之前使用event_time从时间表中获取每个员工记录的记录。这样做很简单:
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
这确实有效,但它太快了。如果员工表中有100条记录,我们正在谈论10秒或更长时间。问题是Access特有的,因为我不能像在MySQL或SQL Server中那样使用其他子查询的last_time_id结果。
我正在寻找有关如何提高速度的提示。不同的查询,索引。东西。
答案 0 :(得分:1)
不确定这样的事情对你有用吗?
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;
(完全未经测试,可能包含拼写错误)
答案 1 :(得分:0)
基本上,您的查询正在运行多个相关子查询,甚至是WHERE
子句中的嵌套子查询。相关查询为每一行分别计算一个值,对应于外部查询。
与@LeeMac类似,只需将所有表格加入到按 employee_id 分组的最大 event_time 的汇总查询中,该 employee_id 将运行一次所有行。 次下面是加入汇总查询的基本FROM
表,员工和 time_notes 表:
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