我有一个Access数据库,其中包含一个表格,其中包含有关我们排序的部分的信息。该表具有自动编号ID字段和110ID,该字段链接到具有部件信息的另一个表。它还包含sortDate,sortShift,排序,报废和修复。我需要找到自上次缺陷(没有报废或修复)以来每个110ID已经分拣了多少部分。
问题是我无法保证信息将按时间顺序输入数据库。因此,对于任何“sortDate”大于上一个缺陷的记录,或者“sortDate”与最后一个缺陷相同但更大的“sortShift”,我需要对“sorted”字段求和,或者使用autonumber id作为最后的手段如果'sortDate'和'sortShift'都匹配。
这是我目前使用的查询:
SELECT SortInfo.[110ID], Sum(SortInfo.Sorted) AS SumOfSorted
FROM SortInfo
WHERE (
((SortInfo.sortdate)>(select top 1 dupe.sortdate from sortinfo as dupe where (((dupe.[110id])=(sortinfo.[110id])) and (((dupe.repaired)<>0) or ((dupe.scrapped)<>0))) order by dupe.sortdate desc, dupe.sortshift desc, dupe.id desc)))
OR (((SortInfo.sortdate)=(select top 1 dupe.sortdate from sortinfo as dupe where (((dupe.[110id])=(sortinfo.[110id])) and (((dupe.repaired)<>0) or ((dupe.scrapped)<>0))) order by dupe.sortdate desc, dupe.sortshift desc, dupe.id desc))
AND ((SortInfo.sortshift)>(select top 1 dupe.sortshift from sortinfo as dupe where (((dupe.[110id])=(sortinfo.[110id])) and (((dupe.repaired)<>0) or ((dupe.scrapped)<>0))) order by dupe.sortdate desc, dupe.sortshift desc, dupe.id desc)))
OR (((SortInfo.sortdate)=(select top 1 dupe.sortdate from sortinfo as dupe where (((dupe.[110id])=(sortinfo.[110id])) and (((dupe.repaired)<>0) or ((dupe.scrapped)<>0))) order by dupe.sortdate desc, dupe.sortshift desc, dupe.id desc))
AND ((SortInfo.sortshift)=(select top 1 dupe.sortshift from sortinfo as dupe where (((dupe.[110id])=(sortinfo.[110id])) and (((dupe.repaired)<>0) or ((dupe.scrapped)<>0))) order by dupe.sortdate desc, dupe.sortshift desc, dupe.id desc))
AND ((SortInfo.ID)>(select top 1 dupe.id from sortinfo as dupe where (((dupe.[110id])=(sortinfo.[110id])) and (((dupe.repaired)<>0) or ((dupe.scrapped)<>0))) order by dupe.sortdate desc, dupe.sortshift desc, dupe.id desc))
)
GROUP BY SortInfo.[110ID];
问题是这非常慢。有没有更好的方法来实现这一目标,从而产生更好的性能?
答案 0 :(得分:0)
您可以使用LEFT OUTER JOIN或NOT EXISTS子查询来代替使用所有这些子查询。我不太多使用Access,所以如果它是Access不符合ANSI标准的那些领域之一,你可能需要调整它们。
SELECT
SI.[110ID],
SUM(SI.Sorted) AS SumOfSorted
FROM
SortInfo SI
LEFT OUTER JOIN SortInfo SI2 ON
SI2.Repaired <> 0 AND
SI2.Scrapped <> 0 AND
(
SI2.SortDate > SI.SortDate OR
(SI2.SortDate = SI.SortDate AND SI2.SortShift > SI.SortShift) OR
(SI2.SortDate = SI.SortDate AND SI2.SortShift = SI.SortShift AND SI2.ID > SI.ID)
)
WHERE
SI2.ID IS NULL
GROUP BY
SI.[110ID]
SELECT
SI.[110ID],
SUM(SI.Sorted) AS SumOfSorted
FROM
SortInfo SI
WHERE
NOT EXISTS
(
SELECT *
FROM
SortInfo SI2
WHERE
SI2.Repaired <> 0 AND
SI2.Scrapped <> 0 AND
(
SI2.SortDate > SI.SortDate OR
(SI2.SortDate = SI.SortDate AND SI2.SortShift > SI.SortShift) OR
(SI2.SortDate = SI.SortDate AND SI2.SortShift = SI.SortShift AND SI2.ID > SI.ID)
)
GROUP BY
SI.[110ID]
)