优雅的方法去除孤立行?

20

我有一张表,其中包含许多历史记录,这些记录包含客户ID。

还有一个单独的客户表。偶尔会删除一些客户条目。

是否有一种简单的方法,可以在不循环遍历每个历史记录的情况下,删除所有历史表中的行,其中客户ID不存在,因为已删除客户行?


你想每次删除客户时都进行删除,还是只定期进行删除? - Ryan Gross
5个回答

35
delete from history_table where customer_id not in (select customer_id from customers)

你的意思是类似于这样吗?


3
它的弱点在于无法处理自连接(例如表中的parentid)。 它可能比适当的连接慢...但在小表上可能不太明显。 - Steve Horvath

16
DELETE h.* FROM history h
LEFT JOIN customer c ON h.customer_id = c.id
WHERE c.id IS NULL
我是根据我的理解打字的,但是希望你能明白我的意思。 删除语法文档

1
这是正确的解决方案。 - Steve Horvath

6
如何考虑:
DELETE FROM history_table 
WHERE customer_id NOT IN (SELECT customer_id FROM customer);

6
你可以使用级联外键来实现这一点。在下面的示例中,每当从A中删除一行或更改A中的A_ID时,此更改都会自动反映在表B中。您可以在MySql文档中阅读有关外键的更多信息
CREATE TABLE A(
   A_ID INT, 
   PRIMARY_KEY(A_ID)
) TYPE=InnoDB;

CREATE TABLE B(
   B_ID INT,
   A_ID INT,
   CONSTRAINT FK_B_A FOREIGN KEY REFERENCES A(A_ID) ON DELETE CASCADE ON UPDATE CASCADE,
   PRIMARY_KEY(B_ID, A_ID)
) TYPE=InnoDB;

由于客户被删除时,其历史记录也必须被删除,因此最好的解决方案是这个。没有必要仅删除父表记录而不删除其子表记录,所以让数据库像@Ryan Gross所说的那样处理吧! - Leandro Jacques
这是最佳解决方案,因为它处理了嵌套引用,您不需要编写第二个查询来删除相关记录。删除父记录就足以删除相关历史记录。 - Taha Paksu

1
DELETE FROM CUSTOMER_HISTORY CH
WHERE NOT EXISTS (SELECT 1 FROM CUSTOMER C WHERE C.CUSTOMER_ID = CH.CUSTOMER_ID)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接