Это можно легко сделать с помощью аналитических (оконных) функций, доступных в Oracle / SQL-Server / etc (Google для lag, lead, first_value, last_value и т. Д. И т. Д.), Но Access не поддерживает их, поэтому вам придется присоединиться к чему-то вроде этого:
SELECT
rows.Job, rows.proj, rows.dte, curr.amt
FROM
((SELECT Data.Job, Data.proj, Data.dte,
(SELECT max(dte)
FROM data as prev
WHERE prev.job = data.job and
prev.proj = data.proj and
prev.dte < data.dte) AS prev_dte
FROM Data) as [rows]
INNER JOIN Data AS curr
ON (rows.dte = curr.dte) AND
(rows.proj = curr.proj) AND
(rows.Job = curr.Job)
)
LEFT JOIN Data AS prev
ON (rows.prev_dte = prev.dte) AND
(rows.proj = prev.proj) AND
(rows.Job = prev.Job)
WHERE
prev.amt<>[curr].[amt] OR
prev.Job Is Null;
Таким образом, встроенное представление с именем [строки] находит максимальную дату меньше, чем каждая дата в вашей таблице, а затем внутреннее соединение обратно, чтобы получить текущую строку, и внешнее соединение для предыдущей строки, чтобы вы могли выбрать первую строку.
(Возникли проблемы с форматированием кода - извините.)
Редактировать: вот вывод, который, я думаю, вам нужен.
Job proj dte amt
Programmer 105 01/01/2011 3
Programmer 105 03/01/2011 2
Programmer 105 05/01/2011 3
Programmer 110 03/01/2011 1
Programmer 110 04/01/2011 2
Programmer 110 05/01/2011 3
Manager 105 01/01/2011 1
Manager 105 02/01/2011 2