Mysql:从一个表中选择不在另一个表中的行
Posted
技术标签:
【中文标题】Mysql:从一个表中选择不在另一个表中的行【英文标题】:Mysql: Select rows from a table that are not in another 【发布时间】:2012-07-30 20:09:49 【问题描述】:如何选择一个表中没有出现在另一个表中的所有行?
表1:
+-----------+----------+------------+
| FirstName | LastName | BirthDate |
+-----------+----------+------------+
| Tia | Carrera | 1975-09-18 |
| Nikki | Taylor | 1972-03-04 |
| Yamila | Diaz | 1972-03-04 |
+-----------+----------+------------+
表2:
+-----------+----------+------------+
| FirstName | LastName | BirthDate |
+-----------+----------+------------+
| Tia | Carrera | 1975-09-18 |
| Nikki | Taylor | 1972-03-04 |
+-----------+----------+------------+
Table1 中不在 Table2 中的行的示例输出:
+-----------+----------+------------+
| FirstName | LastName | BirthDate |
+-----------+----------+------------+
| Yamila | Diaz | 1972-03-04 |
+-----------+----------+------------+
也许这样的事情应该可行:
SELECT * FROM Table1 WHERE * NOT IN (SELECT * FROM Table2)
【问题讨论】:
【参考方案1】:一个选项是
SELECT A.*
FROM TableA as A
LEFT JOIN TableB as B
ON A.id = B.id
Where B.id Is NULL
【讨论】:
【参考方案2】:SELECT *
FROM Table1 AS a
WHERE NOT EXISTS (
SELECT *
FROM Table2 AS b
WHERE a.FirstName=b.FirstName AND a.LastName=b.Last_Name
)
EXISTS
会帮助你...
【讨论】:
很好的答案,对于大型数据集来说很经济,谢谢。 强。大型数据集的最佳答案【参考方案3】:试试这个简单的查询。效果很好。
select * from Table1 where (FirstName,LastName,BirthDate) not in (select * from Table2);
【讨论】:
我喜欢这个,因为一个表中的列名不必与另一个表中的列名相同,它只是比较相应的值(经过测试和工作)。【参考方案4】:这在 Oracle 中对我有用:
SELECT a.*
FROM tbl1 a
MINUS
SELECT b.*
FROM tbl2 b;
【讨论】:
问题是关于 mysql 的。【参考方案5】:SELECT a.* FROM
FROM tbl_1 a
MINUS
SELECT b.* FROM
FROM tbl_2 b
【讨论】:
【参考方案6】:试试:
SELECT * FROM table1
LEFT OUTER JOIN table2
ON table1.FirstName = table2.FirstName and table1.LastName=table2.LastName
WHERE table2.BirthDate IS NULL
【讨论】:
【参考方案7】:如果您在另一条评论中提到有 300 列,并且您想要比较所有列(假设这些列都同名),您可以使用 NATURAL LEFT JOIN
隐式连接所有匹配的列名这两个表,这样您就不必繁琐地手动输入所有连接条件:
SELECT a.*
FROM tbl_1 a
NATURAL LEFT JOIN tbl_2 b
WHERE b.FirstName IS NULL
【讨论】:
请注意,这仅在没有任何列具有 NULL 值时按预期工作。在 MySQL NULL != NULL 中,即使第二个表中有重复行,也会返回具有 NULL 值的每一行。 如果你有 300 列,你应该重新设计你的数据库。 嘿,这对我也有用,谢谢!但是如果像你上面提到的那样行数 > 300,那会是个问题吗? 我仍然对查询 btw 感到困惑。例如,如果我将“b.FirstName 为空”更改为“b.LastName 为空”会怎样?有什么不同?很抱歉问这个问题,我还是 sql 新手:D【参考方案8】:标准的 LEFT JOIN 可以解决问题,如果加入的字段被索引, 也应该更快
SELECT *
FROM Table1 as t1 LEFT JOIN Table2 as t2
ON t1.FirstName = t2.FirstName AND t1.LastName=t2.LastName
WHERE t2.BirthDate Is Null
【讨论】:
好吧,我想一定是这样,顺便说一句,为什么WHERE t2.Birthdate Is Null
而不是AND t1.Birthdate = t2.Birthdate
?
因为如果你添加它,那么每一行都会被返回,你说在输出中应该只出现不在第二个表中的行
这是一个了不起的答案,因为它不需要返回Table2
的所有行!
我同意,很好的答案。我在 4 个表之间有一个多人表,将 AND 放在内部连接中肯定会更经济。【参考方案9】:
您需要根据列名进行子选择,而不是*
。
例如,如果您有两个表共有的 id
字段,您可以这样做:
SELECT * FROM Table1 WHERE id NOT IN (SELECT id FROM Table2)
有关更多示例,请参阅MySQL subquery syntax。
【讨论】:
感谢您的澄清!但我真的不需要根据任何字段来选择行,因为我对行中任何字段的任何变体都感兴趣...... 如果只有几列要比较,您可以按照@Steve 的示例进行连接。如果您实际上要求对具有许多列的两个表中的数据进行一般比较,您可能需要查找MySQL diff tool。 请注意,如果您在 Table2 中查看的列包含空值,这将始终返回一个空集。如果您基于主键执行此操作,则不是问题,但与尝试在其他上下文中使用此查询的人相关。 但是如果我们谈论的是大数据呢?而Table2包含100M行,例如? 聪明而聪明的回答。谢谢老哥以上是关于Mysql:从一个表中选择不在另一个表中的行的主要内容,如果未能解决你的问题,请参考以下文章
MySQL - 如何选择表中的行,其中 id 值位于另一个表中的逗号分隔字段中?
mysql - 如果不在另一个表中,则从一个表中选择,否则从另一个表中选择
从表中选择行,其中具有相同 id 的另一个表中的行在另一列中具有特定值