Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 左连接和内连接差异。。。永远一次_Sql_Join_Left Join_Inner Join - Fatal编程技术网

Sql 左连接和内连接差异。。。永远一次

Sql 左连接和内连接差异。。。永远一次,sql,join,left-join,inner-join,Sql,Join,Left Join,Inner Join,我知道这里有很多关于这个话题的帖子&在互联网上。但我真的不能得到这两种说法之间差异的最后一点!我的意思是,不断地尝试,我可以通过我的查询获得所有我需要的结果,但我真的不能完全控制这把刀 我认为自己是一个非常好的程序员和一个非常好的SQL ista,对此我感到有点惭愧 下面是一个例子: 我有一个包含网站页面的表格(“网页”) 包含类别的表(“类别”) 一个类别可以包含一个或多个页面,但反之亦然 类别可能根本不包含任何页面 网页可以在网站中可见或不可见 因此,如果我想显示所有类别及其页面,我指的

我知道这里有很多关于这个话题的帖子&在互联网上。但我真的不能得到这两种说法之间差异的最后一点!我的意思是,不断地尝试,我可以通过我的查询获得所有我需要的结果,但我真的不能完全控制这把刀

我认为自己是一个非常好的程序员和一个非常好的SQL ista,对此我感到有点惭愧

下面是一个例子:

  • 我有一个包含网站页面的表格(“网页”)
  • 包含类别的表(“类别”)
  • 一个类别可以包含一个或多个页面,但反之亦然
  • 类别可能根本不包含任何页面
  • 网页可以在网站中可见或不可见
因此,如果我想显示所有类别及其页面,我指的是有页面和无页面的类别,我必须这样做:

FROM category
LEFT JOIN web_page ON ( web_page.category_id = category.category_id AND web_page.active = "Y" )
WHERE COALESCE(web_page.active,"Y") = "Y"
因此,如果一个类别没有页面,我会在该类别的记录中看到web_page_id为NULL

但如果我这样做:

FROM category
LEFT JOIN web_page ON ( web_page.category_id = category.category_id )
...
WHERE web_page.active = "Y"...
我将仅选择至少有一个网页的类别。。。但是为什么呢

这只是一个例子。。。我想永远明白这一次的区别


谢谢。

要使您的查询按预期工作,请将该条件放入
ON
子句中:

FROM category
LEFT JOIN web_page ON web_page.category_id = category 
   and web_page.active = "Y"
这样做的原因是(对于大多数数据库,但不是所有数据库),
WHERE
子句在加入行后过滤行。如果联接没有导致网页行联接(因为该类别没有网页),则网页的所有列都将为
null
,并且任何值(如
“Y”
)与
null
的比较都是false,因此这些未联接的行将被过滤掉

但是,通过将条件移动到
ON
子句中,在进行连接时执行该条件,以便只连接
active=“Y”
的行,但如果没有任何这样的行,则只会得到左侧的连接
null
网页

这个版本的查询实际上是在说:“给我所有类别及其活动网页(如果有)”


请注意,我说的是“大多数数据库”。。。例如,mysql非常聪明,能够理解您要做的事情,如果在mysql上运行,您的查询将按预期工作。

这是因为SQL是分阶段处理的:

  • 来自
    子句(所有连接都在这里)
  • 其中
    条款
  • 分组依据
    条款
  • 窗口函数(与MySQL无关)
  • orderby
    子句

  • 因此,如果您想在
    web\u page.active='Y'
    上进行筛选,或者希望以相同的条件加入,这一点非常重要。在前一种情况下,连接完成,您只需过滤掉结果,将
    外部
    连接转换为
    内部
    连接。在后一种情况下,您将获得所需的结果,因为不匹配的行将导致相应列的
    NULL
    值。

    试图帮助您理解部分

    考虑是SQL语言的一个方面,当在
    左连接中指定条件时,它将在查找要匹配的记录时应用。
    当在底部的WHERE子句中指定了条件时,它将应用于所有记录-在连接发生之后。如您所见,这会产生一个意外的副作用,即将
    左连接
    更改为
    内部连接

    您可以通过这样的
    WHERE
    子句来解决这个问题:

    FROM category
    LEFT JOIN web_page ON ( web_page.category_id = category.category_id AND web_page.active = "Y" )
    
    WHERE COALESCE(web_page.active,"Y") = "Y"
    

    但事实上,这并不能保证得到相同的结果,因此正确的方法是将该标准保留在
    JOIN

    +1的
    ON
    子句中。谢谢我总是想知道JOIN中的哪一个或在哪里首先工作。