如何在另一个表中选择没有匹配条目的行?

我正在对一个数据库应用程序进行一些维护工作,我发现,最令人高兴的是,即使一个表的值以外键的样式使用,但表上没有外键约束。

我试图在这些列上添加FK约束,但我发现,因为在以前的错误中已经有大量坏数据,这些错误已经被天真地纠正了,所以我需要找到与另一个表不匹配的行,然后删除它们。

我在网上找到了一些这类查询的例子,但它们似乎都提供了例子而不是解释,我不明白为什么它们能起作用。

有人能向我解释一下如何构造一个查询,返回另一个表中没有匹配的所有行,以及它在做什么,这样我就可以自己进行这些查询,而不是为这个混乱中没有FK约束的每个表运行到so ?

598363 次浏览

这是一个简单的问题:

SELECT t1.ID
FROM Table1 t1
LEFT JOIN Table2 t2 ON t1.ID = t2.ID
WHERE t2.ID IS NULL

重点是:

  1. LEFT JOIN被使用;这将返回Table1中的所有行,而不管Table2中是否有匹配的行。

  2. WHERE t2.ID IS NULL子句;这将限制返回的结果只有那些从Table2返回的ID为空的行-换句话说,对于来自Table1的特定ID,在Table2中有NO记录。对于Table1中ID未在Table2中匹配的所有记录,Table2.ID将返回为NULL。

其中T2是要添加约束的表:

SELECT *
FROM T2
WHERE constrained_field NOT
IN (
SELECT DISTINCT t.constrained_field
FROM T2
INNER JOIN T1 t
USING ( constrained_field )
)

并删除结果。

我会使用EXISTS表达式,因为它更强大,你可以更精确地选择你想要连接的行。在LEFT JOIN的情况下,你必须获取连接表中的所有内容。它的效率可能与带有空约束的LEFT JOIN的情况相同。

SELECT t1.ID
FROM Table1 t1
WHERE NOT EXISTS (SELECT t2.ID FROM Table2 t2 WHERE t1.ID = t2.ID)
SELECT id FROM table1 WHERE foreign_key_id_column NOT IN (SELECT id FROM table2)

表1有一个列,你想在其中添加外键约束,但是foreign_key_id_column中的值并不都与表2中的id相匹配。

  1. 初始选择列出了表1中的__abc。这些就是我们要删除的行。
  2. where语句中的NOT IN子句将查询限制在那些foreign_key_id_column中的值不在表2 __abc2列表中的行。
  3. 括号中的SELECT语句将获得表2中所有__abc1的列表。
让我们有以下两张表(工资和员工) enter image description here < / p >

现在我想从员工表的那些记录不是在工资。 我们可以用3种方法来做到这一点:

  1. 使用内部连接
select * from employee
where id not in(select e.id from employee e inner join salary s on e.id=s.id)

enter image description here

  1. 使用左外连接
select * from employee e
left outer join salary s on e.id=s.id  where s.id is null

enter image description here

  1. 使用完全连接
select * from employee e
full outer join salary s on e.id=s.id where e.id not in(select id from salary)

enter image description here

我不知道哪个是优化的(与@AdaTheDev相比 ),但是当我使用

时(至少对我来说),这个似乎更快
SELECT id  FROM  table_1 EXCEPT SELECT DISTINCT (table1_id) table1_id FROM table_2

如果你想获得任何其他特定的属性,你可以使用:

SELECT COUNT(*) FROM table_1 where id in (SELECT id  FROM  table_1 EXCEPT SELECT DISTINCT (table1_id) table1_id FROM table_2);

如何在两个表中选择没有匹配条目的行?



select * from [dbo].[EmppDetails] e
right join [Employee].[Gender] d on e.Gid=d.Gid
where e.Gid is Null


union
select * from [dbo].[EmppDetails] e
left join [Employee].[Gender] d on e.Gid=d.Gid
where d.Gid is Null


你可以选择的观点,如下所示:

CREATE VIEW AuthorizedUserProjectView AS select t1.username as username, t1.email as useremail, p.id as projectid,
(select m.role from userproject m where m.projectid = p.id and m.userid = t1.id) as role
FROM authorizeduser as t1, project as p

然后对视图进行选择或更新:

select * from AuthorizedUserProjectView where projectid = 49

产生如下图所示的结果,即对于不匹配的列,已填充null。

[Result of select on the view][1]

从类似的问题在这里MySQL内部连接查询获取其他表中不存在的记录我得到了这个工作

SELECT * FROM bigtable
LEFT JOIN smalltable ON bigtable.id = smalltable.id
WHERE smalltable.id IS NULL

smalltable是丢失记录的地方,bigtable是所有记录的地方。该查询列出了在smalltable中不存在但在bigtable中存在的所有记录。你可以用任何其他匹配条件替换id

你可以这样做

   SELECT IFNULL(`price`.`fPrice`,100) as fPrice,product.ProductId,ProductName
FROM `products` left join `price` ON
price.ProductId=product.ProductId AND (GeoFancingId=1 OR GeoFancingId
IS NULL) WHERE Status="Active" AND Delete="No"

SELECT * FROM First_table - SELECT * FROM other