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 vs WHERE子句上的内部联接_Sql_Mysql_Join_Inner Join - Fatal编程技术网

Sql vs WHERE子句上的内部联接

Sql vs WHERE子句上的内部联接,sql,mysql,join,inner-join,Sql,Mysql,Join,Inner Join,为简单起见,假设所有相关字段均非空 你可以做: SELECT table1.this, table2.that, table2.somethingelse FROM table1, table2 WHERE table1.foreignkey = table2.primarykey AND (some other conditions) 否则: SELECT table1.this, table2.that, table2.somethingelse F

为简单起见,假设所有相关字段均
非空

你可以做:

SELECT
    table1.this, table2.that, table2.somethingelse
FROM
    table1, table2
WHERE
    table1.foreignkey = table2.primarykey
    AND (some other conditions)
否则:

SELECT
    table1.this, table2.that, table2.somethingelse
FROM
    table1 INNER JOIN table2
    ON table1.foreignkey = table2.primarykey
WHERE
    (some other conditions)

MySQL
中,这两个函数是否以相同的方式工作?

内部连接是您应该使用的ANSI语法

它通常被认为更具可读性,尤其是当您连接许多表时

只要有需要,它也可以很容易地用
外部连接替换

WHERE
语法更面向关系模型

两个表
JOIN
ed的结果是对其应用筛选器的表的笛卡尔乘积,该筛选器仅选择那些具有匹配的联接列的行

使用
WHERE
语法更容易看到这一点

就您的示例而言,在MySQL中(通常在SQL中),这两个查询是同义词

另外,请注意MySQL还有一个
stright\u JOIN
子句

使用此子句,您可以控制
联接的顺序:哪个表在外循环中扫描,哪个表在内循环中扫描

在MySQL中,您无法使用
WHERE
语法来控制这一点。

隐式连接(这是您的第一个查询所称的连接)在需要开始向查询添加更多表时变得更加混乱、难以读取和维护。想象一下,在四个或五个不同的表上执行相同的查询和连接类型。。。这是一场噩梦


使用显式连接(您的第二个示例)更易于阅读和维护

它们具有不同的人类可读的含义

但是,根据查询优化器的不同,它们对机器可能具有相同的含义

您应该始终编写可读的代码


也就是说,如果这是一个内置关系,则使用显式连接。如果要在弱相关数据上进行匹配,请使用where子句。

隐式join ANSI语法较旧,不太明显,不推荐使用

此外,关系代数允许
WHERE
子句和
internaljoin
中谓词的互换性,因此,即使是
internaljoin
查询
WHERE
子句,优化器也可以重新排列谓词

我建议您以尽可能可读的方式编写查询

有时,这包括使
内部联接相对“不完整”,并将一些条件放在
中的
位置,以使筛选条件列表更易于维护

例如,而不是:

SELECT *
FROM Customers c
INNER JOIN CustomerAccounts ca
    ON ca.CustomerID = c.CustomerID
    AND c.State = 'NY'
INNER JOIN Accounts a
    ON ca.AccountID = a.AccountID
    AND a.Status = 1
写:

SELECT *
FROM Customers c
INNER JOIN CustomerAccounts ca
    ON ca.CustomerID = c.CustomerID
INNER JOIN Accounts a
    ON ca.AccountID = a.AccountID
WHERE c.State = 'NY'
    AND a.Status = 1

当然,这要看情况而定。

其他人已经指出,
内部连接
有助于人类的可读性,我同意这是一个首要任务。
让我试着解释一下为什么连接语法更具可读性

基本的
SELECT
查询如下:

SELECT stuff
FROM tables
WHERE conditions
SELECT
子句告诉我们得到了什么;
FROM
子句告诉我们从哪里获得,而
where
子句告诉我们从哪里获得

JOIN
是关于表的语句,它们是如何绑定在一起的(从概念上讲,实际上是绑定到单个表中的)


任何控制表的查询元素(我们从中获取内容)在语义上都属于
from
子句(当然,这就是
JOIN
元素的位置)。将连接元素放入
WHERE
子句会将whichWHERE from合并在一起,这就是为什么首选
JOIN
语法。

我还将指出,使用旧语法更容易出错。如果使用不带ON子句的内部联接,将出现语法错误。如果使用较旧的语法并忘记where子句中的一个连接条件,则会得到交叉连接。开发人员通常通过添加distinct关键字(而不是修复连接,因为他们仍然没有意识到连接本身已损坏)来解决此问题,这似乎可以解决问题,但会大大降低查询速度

此外,对于维护,如果您在旧语法中有交叉连接,那么维护人员如何知道您是否打算使用交叉连接(有些情况下需要交叉连接),或者这是一个应该修复的事故

让我指出这个问题,看看如果使用左连接,隐式语法为什么不好。


另外,使用显式连接的标准已经有20多年的历史了,这意味着隐式连接语法已经过时20年了。你会使用已经过时20年的语法编写应用程序代码吗?为什么要编写这样的数据库代码?

ANSI join语法肯定更具可移植性


我正在进行Microsoft SQL Server的升级,我还想指出,2005 SQL Server及更高版本不支持SQL Server中外部联接的=*和*=语法(不支持兼容模式)。

我知道您在谈论MySQL,但无论如何:
在Oracle 9中,显式联接和隐式联接将生成不同的执行计划。甲骨文10+解决了一个问题:不再有这样的区别了

SQL:2003标准更改了一些优先规则,因此JOIN语句优先于“逗号”联接。这实际上会改变查询的结果,具体取决于查询的设置方式。当MySQL 5.0.12切换到遵循该标准时,这会给一些人带来一些问题

因此,在您的示例中,您的查询的工作原理相同。但如果添加了第三个表: 选择。。。从表1、表2到表3。。。在哪里

在MySQL 5.0.12之前,表1和表2将首先连接,然后是表3。现在(5.0.12及更高版本),首先连接表2和表3,然后连接表1。它并不总是改变结果,但它可以,你甚至可能没有意识到

我再也不用“逗号”了,optin
(8)  SELECT (9) DISTINCT (11) TOP <top_specification> <select_list>
(1)  FROM <left_table>
(3)       <join_type> JOIN <right_table>
(2)       ON <join_condition>
(4)  WHERE <where_condition>
(5)  GROUP BY <group_by_list>
(6)  WITH {CUBE | ROLLUP}
(7)  HAVING <having_condition>
(10) ORDER BY <order_by_list>