19

当我执行以下查询时:

SELECT * FROM `table1` 
 INNER JOIN table2 ON table2.number = table1.number

我在 2 秒内得到结果。大约有 600 万条记录table2和 100 万条记录table1

table2.number并被table1.number索引。

现在我想得到一个不存在的数字列表。像这样:

SELECT * FROM `table1` 
 INNER JOIN table2 ON table2.number != table1.number

它需要永远并且仍然挂起..如何解决?

4

4 回答 4

47

假设您的第一个INNER JOIN返回 75% 的 1,000,000 行table1。第二个查询不会像您想象的那样返回 250,000 行。相反,它会尝试创建笛卡尔积并删除 750,000 个匹配行。因此它试图返回 6,000,000×1,000,000-750,000 行。这是一个膨胀的 6×10 12行结果集。

你可能想要这个:

SELECT * FROM table1
LEFT JOIN table2 ON table2.number = table1.number
WHERE table2.number IS NULL

这将返回中table1不存在的行table2

您可能还对以下内容感兴趣FULL OUTER JOIN

SELECT * FROM table1
FULL OUTER JOIN table2 ON table2.number = table1.number
WHERE table1.number IS NULL AND table2.number IS NULL

这将返回两个表中在另一个表上没有匹配项的行。

于 2012-12-13T16:10:21.447 回答
7

这不起作用的原因是您基本上将 table1 的每一行与表 2 的每一行连接起来。您需要一些东西来加入它。最好的方法是进行左连接(意味着无论如何它都会连接 table1,但不会连接 table2),然后检查以确保 table2 没有为 null 的条目。然后,您需要对 table2 执行相同的操作。

SELECT * FROM `table1` 
LEFT JOIN table2 ON table2.number = table1.number 
WHERE table2.number is NULL

UNION

SELECT * FROM `table2` 
LEFT JOIN table1 ON table2.number = table1.number 
WHERE table1.number is NULL
于 2012-12-13T16:07:54.970 回答
2

而不是这个,你可以使用这个方法:

SELECT * FROM `table1` 
     LEFT JOIN table2 ON table2.number = table1.number 
WHERE 
     table2.number is NULL OR table1.number is NULL
于 2017-05-08T05:22:40.527 回答
0

@Álvaro González 当我们想要返回不匹配的记录时,完整的外连接查询不应该使用 OR 而不是 AND:AND 永远不会返回任何记录。

SELECT * FROM table1 FULL OUTER JOIN table2 ON table2.number = table1.number WHERE table1.number IS NULL OR table2.number IS NULL

于 2021-01-18T15:32:25.987 回答