简体   繁体   English

为每个组选择前1名

[英]Select top 1 for each group

I have an Access database that contains a table with information about parts we sort. 我有一个Access数据库,其中包含一个表,其中包含有关我们排序的零件的信息。 This table has an autonumber ID field and a 110ID that links to another table with the part information. 该表具有一个自动编号ID字段和一个110ID,该ID链接到带有零件信息的另一个表。 It also contains a sortDate, sortShift, sorted, scrapped, and repaired. 它还包含sortDate,sortShift,已排序,报废和修复。 I need to find how many parts have been sorted since the last defect (none scrapped or repaired) was found for each 110ID. 我需要找到自从找到每个110ID的最后一个缺陷(没有报废或修复)以来已分类的零件数量。

The problem is that I cannot guarantee that the information will be entered into the database in chronological order. 问题是我不能保证信息将按时间顺序输入到数据库中。 So I need sum the 'sorted' field for any records that have a 'sortDate' greater than the last defect, or a 'sortDate' the same as the last defect but greater 'sortShift', or use the autonumber id as a last resort if both the 'sortDate' and 'sortShift' match. 因此,对于所有具有大于最后一个缺陷的“ sortDate”或与最后一个缺陷相同但大于“ sortShift”的“ sortDate”的记录,我需要对“ sorted”字段求和,或者将自动编号id作为最后的求助方法如果'sortDate'和'sortShift'都匹配。

This is the query I am currently using: 这是我当前正在使用的查询:

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];

The problem is that this is extremely slow. 问题是这非常慢。 Is there a better way to accomplish this that will yield better performance? 是否有更好的方法来完成此操作,从而获得更好的性能?

Instead of using all of those subqueries, you can do this with either a LEFT OUTER JOIN or a NOT EXISTS subquery. 可以使用LEFT OUTER JOIN或NOT NOTISTS子查询来代替使用所有这些子查询。 I don't use Access much, so you may need to tweak these if it's one of those areas where Access falls short of following the ANSI standard. 我使用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]
    )

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM