为简单起见,假设全部相关字段都不为NOT NULL
。 优化
你能够作: this
SELECT table1.this, table2.that, table2.somethingelse FROM table1, table2 WHERE table1.foreignkey = table2.primarykey AND (some other conditions)
要否则: spa
SELECT table1.this, table2.that, table2.somethingelse FROM table1 INNER JOIN table2 ON table1.foreignkey = table2.primarykey WHERE (some other conditions)
这两个在MySQL
是否以相同的方式工做? code
INNER JOIN
是您应该使用的ANSI语法。 element
一般认为它更具可读性,尤为是当您链接许多表时。 it
若有须要,也能够轻松地将其替换为OUTER JOIN
。 io
WHERE
语法更面向关系模型。 table
两个表JOIN
ed的结果是表的笛卡尔积,将对其应用过滤器,该过滤器仅选择链接列匹配的那些行。 循环
使用WHERE
语法更容易看到这一点。 语法
以您的示例为例,在MySQL(一般在SQL中)中,这两个查询是同义词。
另请注意,MySQL还具备STRAIGHT_JOIN
子句。
使用此子句,您能够控制JOIN
顺序:在外部循环中扫描哪一个表,在内部循环中扫描哪一个表。
您没法使用WHERE
语法在MySQL中控制此功能。
一旦您须要开始向查询中添加更多表,隐式联接(这就是您的第一个查询所称的)变得更加混乱,难以阅读且难以维护。 想象一下在四个或五个不一样的表上执行相同的查询和联接类型……这是一场噩梦。
使用显式联接(第二个示例)更加易读且易于维护。
它们具备不一样的人类可读含义。
可是,取决于查询优化器,它们对计算机可能具备相同的含义。
您应该始终编写可读性强的代码。
也就是说,若是这是内置关系,请使用显式联接。 若是要匹配弱关联的数据,请使用where子句。
隐式链接ANSI语法较旧,不太明显,不建议使用。
此外,关系代数容许WHERE
子句中的谓词和INNER JOIN
互换,所以即便带有WHERE
子句的INNER JOIN
查询也能够使谓词由优化程序从新排列。
我建议您以最可行的方式编写查询。
有时,这包括使INNER JOIN
相对“不完整”,并将某些条件放在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
但这固然取决于。
其余人指出,INNER JOIN有助于提升人类可读性,这是当务之急。 我赞成。 让我尝试解释为何联接语法更具可读性。
基本的SELECT查询是这样的:
SELECT stuff FROM tables WHERE conditions
SELECT子句告诉咱们, 正是咱们找回; FROM子句告诉咱们在那里咱们获得它,而且在WHERE子句告诉咱们,咱们获得哪些 。
JOIN是有关表的声明,说明如何将它们绑定在一块儿(实际上,其实是绑定到单个表中)。 从语义上讲,控制表的任何查询元素-咱们从那里获取东西-都属于FROM子句(固然,这就是JOIN元素所在的位置)。 将joining-elements放入WHERE子句中,能够将which和where-from放宽; 这就是为何首选JOIN语法的缘由。