在连接条件上使用IS NULL或IS NOT NULL-理论问题

在连接条件上使用IS NULL或IS NOT NULL-理论问题,第1张

在连接条件上使用IS NULL或IS NOT NULL-理论问题

表A和B的示例:

 A (parent)       B (child)    ============    ============= id | name        pid | name ------------    -------------  1 | Alex         1  | Kate  2 | Bill         1  | Lia  3 | Cath         3  | Mary  4 | Dale       NULL | Pan  5 | Evan

如果要查找父母及其子女,请执行以下 *** 作

INNER JOIN

SELECt id,  parent.name AS parent     , pid, child.name  AS childFROM        parent  INNER JOIN  child  ON   parent.id     =    child.pid

结果是,左表中的s 与第二个表中

parent
的s的每个匹配项都将在结果中显示为一行:
id``child``pid

+----+--------+------+-------+| id | parent | pid  | child | +----+--------+------+-------+|  1 | Alex   |   1  | Kate  ||  1 | Alex   |   1  | Lia   ||  3 | Cath   |   3  | Mary  |+----+--------+------+-------+

现在,上面没有显示没有孩子的父母(因为他们的ID与孩子的ID不匹配,所以您要怎么做?您改为进行外部联接。外部联接有三种类型,左联接,右联接和完整的外部联接,我们需要左边的联接,因为我们想要左边表(父表)中的“额外”行:

SELECt id,  parent.name AS parent     , pid, child.name  AS childFROM        parent  LEFT JOIN  child  ON   parent.id    =    child.pid

结果是,除了以前的比赛之外,还会显示所有没有比赛的父母(读:没有孩子):

+----+--------+------+-------+| id | parent | pid  | child | +----+--------+------+-------+|  1 | Alex   |   1  | Kate  ||  1 | Alex   |   1  | Lia   ||  3 | Cath   |   3  | Mary  ||  2 | Bill   | NULL | NULL  ||  4 | Dale   | NULL | NULL  ||  5 | Evan   | NULL | NULL  |+----+--------+------+-------+

这些

NULL
都是从哪里来的?那么,MySQL的(或任何其他RDBMS,你可以使用),不知道该怎么把那里作为这些父母没有匹配(孩子),所以没有
pid
也不会
child.name
以配合这些父母。因此,它将这个特殊的非值称为
NULL

我的观点是,这些

NULLs
是在期间创建的(在结果集中)
LEFT OUTER JOIN


因此,如果我们只想显示没有孩子的父母,则可以

WHERe child.pid IS NULL
LEFT JOIN
上面添加一个。完成
后将评估(检查)
WHERe
子句
JOIN
。因此,从上面的结果可以清楚地看到,只有最后三行(其中
pid
NULL为)将显示:

SELECt id,  parent.name AS parent     , pid, child.name  AS childFROM        parent  LEFT JOIN  child  ON   parent.id    =    child.pidWHERe child.pid IS NULL

结果:

+----+--------+------+-------+| id | parent | pid  | child | +----+--------+------+-------+|  2 | Bill   | NULL | NULL  ||  4 | Dale   | NULL | NULL  ||  5 | Evan   | NULL | NULL  |+----+--------+------+-------+

现在,如果我们将

IS NULL
检查从
WHERe
移到加入
ON
子句,会发生什么?

SELECt id,  parent.name AS parent     , pid, child.name  AS childFROM        parent  LEFT JOIN  child  ON   parent.id    =    child.pid  AND  child.pid IS NULL

在这种情况下,数据库尝试从两个表中找到符合这些条件的行。也就是说,其中

parent.id = child.pid
AND
所在的行
child.pid IN NULL
。但是它找不到 这样的匹配项, 因为no
child.pid
不能等于某个值(1、2、3、4或5)并且同时为NULL!

因此,条件:

ON   parent.id    =    child.pidAND  child.pid IS NULL

等效于:

ON   1 = 0

总是这样

False

那么,为什么它返回左表中的所有行? 因为这是左联接! 左联接返回 匹配的行(在这种情况下为无) ,也返回 左表中与 检查
不匹配 的行( 在本例中为全部 ):

+----+--------+------+-------+| id | parent | pid  | child | +----+--------+------+-------+|  1 | Alex   | NULL | NULL  ||  2 | Bill   | NULL | NULL  ||  3 | Cath   | NULL | NULL  ||  4 | Dale   | NULL | NULL  ||  5 | Evan   | NULL | NULL  |+----+--------+------+-------+

我希望以上解释清楚。



旁注(与您的问题没有直接关系):为什么

Pan
我们的JOIN都没有出现?由于在SQL(非常见)逻辑中,他的
pid
is
NULL
和NULL不等于任何值,因此它不能与任何父ID(即1,2,3,4和5)匹配。即使那里有NULL,它也不会匹配,因为
NULL
它不等于任何东西,甚至不等于
NULL
本身(确实是一个非常奇怪的逻辑!)。这就是为什么我们使用特殊支票
ISNULL
而不是
= NULL
支票的原因。

那么,

Pan
如果我们做一个会出现
RIGHT JOIN
吗?是的,它会的!因为RIGHT JOIN将显示所有匹配的结果(我们做的第一个INNER
JOIN)以及RIGHT表中所有不匹配的行(在我们的例子中是
(NULL, 'Pan')
行)。

SELECt id,  parent.name AS parent     , pid, child.name  AS childFROM        parent  RIGHT JOIN  child  ON   parent.id     =    child.pid

结果:

+------+--------+------+-------+| id   | parent | pid  | child | +---------------+------+-------+|   1  | Alex   |   1  | Kate  ||   1  | Alex   |   1  | Lia   ||   3  | Cath   |   3  | Mary  || NULL | NULL   | NULL | Pan   |+------+--------+------+-------+

不幸的是,MySQL没有

FULL JOIN
。您可以在其他RDBMS中尝试它,它将显示:

+------+--------+------+-------+|  id  | parent | pid  | child | +------+--------+------+-------+|   1  | Alex   |   1  | Kate  ||   1  | Alex   |   1  | Lia   ||   3  | Cath   |   3  | Mary  ||   2  | Bill   | NULL | NULL  ||   4  | Dale   | NULL | NULL  ||   5  | Evan   | NULL | NULL  || NULL | NULL   | NULL | Pan   |+------+--------+------+-------+


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5014812.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-14
下一篇 2022-11-15

发表评论

登录后才能评论

评论列表(0条)

保存