这两个SQL查询之间的区别

时间:2016-09-21 19:11:01

标签: mysql sql join

所以我正在测试2个查询,但我得到了不同的结果。我想纠正/修补我的理解。根据我的理解,这里有两个通用的SQL查询是相同的,但执行时得到的结果不同。请注意,这不是关于diff between ANSI and non-ANSI SQL的问题。

查询1(使用LEFT JOIN):

SELECT * FROM person p LEFT JOIN person_log pl
ON p.person_id = pl.person_id
WHERE pl.person_id IS NULL
AND p.is_active = 1;

查询2(使用2个查询):

SELECT * FROM person
WHERE person.is_active = 1
AND person_id NOT IN (SELECT person_id FROM person_log);

根据我的理解,represent this in venn diagram form。还有,比另一个更有效吗?查询JOIN结果与2个查询?

编辑:在查询1中将=更改为IS。感谢@Justin Samuel发现导致不同结果的=错误!

4 个答案:

答案 0 :(得分:2)

上述查询中有一个错误1.您不能使用" ="检查它是否为NULL

SELECT * FROM person p LEFT JOIN person_log pl
ON p.person_id = pl.person_id
WHERE pl.person_id = NULL
AND p.is_active = 1;

理想情况下,您应该使用IS NULL

SELECT * FROM person p LEFT JOIN person_log pl
ON p.person_id = pl.person_id
WHERE pl.person_id IS NULL
AND p.is_active = 1;

您可以查看https://www.simple-talk.com/sql/t-sql-programming/how-to-get-nulls-horribly-wrong-in-sql-server/

中的NULL检查

答案 1 :(得分:1)

两个查询都会为您提供相同的数据。

第二个问题是解决问题的直接方法;获取所有在person_log中没有条目的人。您可以使用NOT EXISTS子句而不是NOT IN子句执行相同操作。 (NOT IN有点精简,但您在子查询中选择的值不能为空,否则您根本看不到任何数据。我通常会IN / NOT IN超过{{ 1}} / EXISTS因为它们的简单,但这是个人偏好的问题。

第一个查询称为反连接。在没有很好地实现这些方法的弱数据库系统上实现与NOT EXISTSNOT EXISTS查询相同的技巧。 (原因是当编写新的数据库系统时,程序员通常会将所有工作都放在连接中,因为它们非常重要并且忽略了NOT INEXISTS一段时间。)

这取决于最快执行的DBMS,INNOT IN或反连接。无论您选择哪种语法,理想的DBMS都会达到相同的执行计划。

反连接可以产生大的中间结果。使用成熟的DBMS,您不应该因为这个原因而仅使用反连接。

答案 2 :(得分:0)

如果要查找第二个表中不匹配的行,尤其是列不可为空时,请使用NOT IN。

答案 3 :(得分:0)

第一个获取所有没有日志条目的人,然后过滤掉不活动的条目。

第二个查询获取所有人。然后过滤掉非活动状态。然后获取所有日志条目。然后筛选出没有日志条目的人。

他们都将返回相同的信息。但是,出于性能原因,如果可以使用JOIN,则应避免像第二个查询。 JOIN的主要好处是索引。 WHERE中只使用一个索引,但每个JOIN将使用一个索引。