Delete unmatched records in Access
I have a table in an Access database where records may be referenced from either of two other tables. I need to delete records from that table if they are not referenced by either of the others. My best solution so far has been to create a subquery to return the id's of the referenced records and to refer to the subquery from a delete query. (The subquery has to be separate because Access does not allow UNION in nested subqueries.)
So ...
SelectQuery:SELECT TableB.id FROM TableB INNER JOIN TableA ON TableB.id = TableA.id
UNION
SELECT TableC.id FROM TableC INNER JOIN TableA ON TableC.id = TableA.id
DeleteQuery:
DELETE * FROM TableA WHERE id NOT IN (SELECT * FROM SelectQuery)
This is excruciatingly slow ... there must be a bette开发者_JAVA技巧r way?
I was trying to avoid having to add a boolean 'Used
' field to TableA ...
@Matthew PK suggests using two NOT IN subqueries, which is theoretically a good idea, but as I observed in a comment, NOT IN and NOT EXISTS are poorly optimized by Jet/ACE and will often not use the indexes on both sides of the comparison. I'm wondering whether or not subqueries are necessary or not:
DELETE *
FROM (TableA LEFT JOIN TableB ON TableA.ID = TableB.ID) LEFT JOIN TableC ON TableA.ID = TableC.ID
WHERE TableB.ID Is Null AND TableC.ID Is Null;
This would definitely use your indexes. If a subquery is necessary, you could replace TableB and TableC with the relevant subqueries.
Why not something like this:
DELETE FROM TableA
WHERE
id NOT IN (SELECT id FROM TableB)
AND
id NOT IN (SELECT id FROM TableC)
?
Is it acceptable to create a new table based on your SelectQuery, delete the original table, and rename the new one to the original name?
/* delete more records */
DELETE FROM table1
WHERE NOT EXISTS
(SELECT field FROM table2 WHERE table2.field = table1.field)
精彩评论