如何在另一个表中select没有匹配条目的行?
我正在做一些数据库应用程序的维护工作,并且我发现,尽pipe来自一个表的值是以外键的forms使用,但是在表中没有外键约束。
我试图在这些列上添加FK约束,但是我发现,因为从以前的错误已经被天真地纠正,表中已经有一个坏数据的负载,我需要find行匹配到另一个表,然后删除它们。
我在网上find了这种查询的一些例子,但是他们似乎都提供了例子而不是解释,我不明白他们为什么会这样工作。
有人可以向我解释如何构build一个查询,它返回所有在另一个表中没有匹配的行,以及它在做什么,这样我就可以自己做这些查询,而不是为了这个混乱中的每个表而跑到SO没有FK限制?
这是一个简单的查询:
SELECT t1.ID FROM Table1 t1 LEFT JOIN Table2 t2 ON t1.ID = t2.ID WHERE t2.ID IS NULL
关键是:
-
LEFT JOIN
; 这将返回Table1
所有行,无论Table1
中是否存在匹配的行。 -
WHERE t2.ID IS NULL
子句; 这将限制返回的结果只返回从Table2
返回的ID为空的那些行 – 换句话说Table2
没有logging来自Table1
特定ID。 对于Table1
中ID不匹配的Table1
中的所有logging,Table2.ID
将返回为NULL。
我会使用EXISTS
expression式,因为它是更强大的,你可以更准确地select你想join的行,在LEFT JOIN
情况下,你必须把所有的东西join表中。 其效率可能与LEFT JOIN
与空testing的情况相同。
SELECT t1.ID FROM Table1 t1 WHERE NOT EXISTS (SELECT t2.ID FROM Table2 t2 WHERE t1.ID = t2.ID)
T2
是要添加约束的表:
SELECT * FROM T2 WHERE constrain_field NOT IN ( SELECT DISTINCT t.constrain_field FROM T2 INNER JOIN T1 t USING ( constrain_field ) )
并删除结果。
SELECT id FROM table1 WHERE foreign_key_id_column NOT IN (SELECT id FROM table2)
表1有一个要添加外键约束的列,但foreign_key_id_column中的值并不全都与表2中的一个id相匹配。
- 最初的select列出了来自table1的id。 这些将是我们想要删除的行。
- where语句中的“not in”子句将查询限制为只有foreign_key_id_column中的值不在table 2 id列表中的行。
- 括号中的select语句将得到表2中所有id的列表。