为什么MySQL的LEFT JOIN在使用WHERE子句时返回"NULL"记录?

sim*_*imm 9 php mysql sql left-join where

今天我尝试了一些更复杂的MySQL查询,我注意到MySQL的LEFT JOIN不能与WHERE子句一起使用.我的意思是,它确实会返回一些记录,但它不会返回右侧为空的记录.

例如,假设我们需要表格:

albums                                   ; albums_rap
  id artist        title         tracks  ;    id artist    title           rank
---- -------- ---------- --------------- ;  ---- --------- ----- --------------
   1 John Doe     Mix CD              20 ;     3 Mark      CD #7            15
   2 Mark          CD #7              35 ;

当我运行此查询时:

SELECT 
    t1.artist as artist,
    t1.title as title,
    t1.tracks as tracks,
    t2.rank as rank,
FROM
    albums as t1
LEFT JOIN
    albums_rap as t2
ON 
    t1.artist LIKE t2.artist
AND
    t1.title LIKE t2.title
WHERE
    t2.rank != 17
Run Code Online (Sandbox Code Playgroud)

我明白了:

artist title tracks  rank
------ ----- ------ -----
Mark   CD #7     35    15

但是当我在这个查询中用"AND"替换"WHERE"时,我得到:

artist     title tracks  rank
------ --------- ------ -----
Mark       CD #7     35    15
John Doe  Mix CD     20  NULL

为什么第一个没有返回带有"NULL"的记录(null不等于17 ...)

我希望你明白我的意思,你会以某种方式解释我的不同之处.对不起我的英语不好,这不是我的母语.

akh*_*ala 32

左连接条件和条件过滤器不同.物理连接完成后,数据将由where子句过滤.如果你看一个左连接它通常会返回左表中的每一行,但是一旦你有一个where子句,它将过滤连接的输出,所以结果就像一个内连接.您将需要关注下图中左侧的两个图表.

在此输入图像描述


Adi*_*uru 5

一旦了解了 SQL 语句的执行顺序或逻辑查询处理阶段,这个问题的解决方案就变得非常直观。顺序是:-

1. FROM
2. ON
3. OUTER
4. WHERE
5. GROUP BY
6. CUBE | ROLLUP
7. HAVING
8. SELECT
9. DISTINCT
10. ORDER BY
11. TOP
Run Code Online (Sandbox Code Playgroud)

由于 ON 在 JOIN 的 OUTER(LEFT/RIGHT) 部分(添加 NULL 值行)之前执行,因此第一种情况在排名列中包含具有 NULL 值的行。在第二种情况下,执行 OUTER JOIN(此处为 LEFT JOIN)后,根据排名列的值过滤掉行。因此,排名列中具有 NULL 值的行将被过滤掉。

在 SQL 查询中可以注意到的一件非常重要的事情是与 NULL 的比较, 这个区域需要特别注意,因为当使用 NULL/NON-NULL 值使用普通算术运算符时,结果为 NULL(既不是 TRUE 也不是 FALSE),因为 NULL 值NULL 表示没有可用于比较的值。此行为在 ANSI SQL-92 标准中定义。(可以通过在某些 SQL 处理器中关闭ansi null(实际名称可能有所不同)参数来覆盖此行为)因此,带有 where 子句的 SQL 查询会过滤掉排名中具有 NULL 值的行由于“17!= NULL”而显得违反直觉的列似乎是正确的——

NULL = NULL 结果 NULL/未知

17 = NULL 结果 NULL/未知

17 != NULL 结果 NULL?未知

一些有趣的帖子/博客可供参考:

http://blog.sqlauthority.com/2009/04/06/sql-server-logic-query-processing-phases-order-of-statement-execution/ http://blog.sqlauthority.com/2009/03/ 15/sql-server-interesting-observation-of-on-clause-on-left-join-how-on-clause-effects-resultset-in-left-join/ http://www.xaprb.com/blog/ 2006/05/18/为什么 null-never-compares-false-to-anything-in-sql/