我有一个父表和一个子表。父行存储子行的外键。如果我将外键的约束设置为 ON DELETE CASCADE,那么当我想要删除父行(其中外键指向其他父行正在使用的子行)时,就会抛出错误。
此 SQL 查询列出了子行以及它们出现的次数。父行是人,子行是国家。
SELECT country_id, country, COUNT(person.id) FROM nobel_prizes.person JOIN nobel_prizes.countries c on c.id = person.country_id GROUP BY country_id;
使用此结果,我可以轻松删除孤立行。但有没有更合适的方法来做到这一点?
我认为你有几个概念颠倒了。
习惯上将带有外键的表称为子表。外键引用的表称为父表。在您的情况下,
person
表是 countries
表的子项,而不是相反。
如果您使用
person
选项在 ON DELETE CASCADE
中定义外键,则从 countries
中删除父行会导致删除 person
中引用已删除行的所有子行也被删除。
孤行是没有父行的行。这违反了引用完整性。
不存在声明性引用完整性(又名外键)支持的反向级联操作。也就是说,如果您删除给定国家/地区的
person
中的最后一行,则不会删除该国家/地区。 countries
中的行有零个子行依赖于它,这并不违反引用完整性。那不是孤儿,只是一个还没有孩子的父母。如果您想手动查找引用它的人数为零的国家/地区,请使用如下查询:
person
在这种情况下,您需要使用外连接,因为内连接只会匹配
SELECT country_id, country, COUNT(person.id)
FROM nobel_prizes.person
LEFT OUTER JOIN nobel_prizes.countries c on c.id = person.country_id
GROUP BY country_id
HAVING COUNT(person.id) = 0;
中那些在
countries
中具有一个或多个匹配行的行。要查找无子项的国家/地区,您特别需要 person
中子行为零的国家/地区。我不认为需要从 person
中删除行。目前地球上只有 195 个国家。