开发者

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)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜