Хм ... Я не слишком разбираюсь в синтаксисе и использовании Access, так что это может быть не совсем применимо.
Возможно, что сложенный запрос генерирует временную таблицу, которая не отсортирована. Таблицы в SQL (не очень уверенные в Access) имеют без присущего порядка . Следовательно, возможно, что когда он ссылается на составленные строки запроса, план доступа генерирует изменения на основе ссылочных столбцов, пытаясь оптимизировать выбранный путь.
В любом случае, я не совсем доволен ни одним из этих запросов, что-то просто отвлекает меня. Вероятно, это постоянное повторное использование SELECT TOP 1
- обычно я бы предпочел использовать пару CTE для достижения эффекта, но я не думаю, что они доступны в Access. Итак, вот некоторые изменения:
Прежде всего, вы можете захотеть изменить с помощью SortDate
, SortShift
и Sort.Id
на простую временную метку (вы пытаетесь найти все с момента возникновения конкретной проблемы, верно?).
Кроме того, вы слишком много заботитесь о значениях «предыдущих» строк, когда вам нужно заботиться о значениях текущих (желательных) строк (я иногда попадаю в это , тоже). Вы не заботитесь о самой верхней строке - наши результаты должны быть больше, чем все строк с дефектами.
Итак, если Sort.id
постоянно увеличивается, а значения НЕ используются повторно, вы просто сможете использовать это единственное значение, что-то вроде этого (может быть в синтаксисе Access ):
SELECT a.[OccurrenceId], SUM(a.sorted) as totalSorted
FROM Sort as a
LEFT JOIN Sort as b
ON b.[OccurrenceId] = a.[OccurrenceId]
AND (b.scrapped > 0 -- This is a count, right?
OR b.repaired > 0) -- see above
AND b.id > a.id
WHERE b.id IS NULL
GROUP BY a.[OccurrenceId]
, который в основном получает все строки, в которых нет «больших» строк (Sort.id
) с scrapped
или repaired
не положительными для данного вхождения. Обратите внимание, что при написании вашего запроса, если в «самой большой» строке есть какие-то списки или исправления, она вернет эту строку, без указания того, что это «неудачный» запуск.
Если Sort.id
используется повторно (это может быть за смену, учитывая его использование), это усложняется:
SELECT a.OccurrenceId, SUM(a.sorted) as totalSorted
FROM Sort as a
LEFT JOIN Sort as b
ON b.[OccurrenceId] = a.[OccurrenceId]
AND (b.scrapped > 0
OR b.repaired > 0)
AND (b.sortDate > a.sortDate
OR (b.sortDate = a.sortDate
AND b.sortShift > a.sortShift)
OR (b.sortDate = a.sortDate
AND b.sortShift = a.sortShift
AND b.id > a.id))
WHERE b.id IS NULL
GROUP BY a.[OccurrenceId]
Я не гарантирую, что любая из этих версий будет быстрее, хотя, вероятно, будет. Они, однако, гораздо менее «искажены».