题
为了简单起见,假定所有相关领域是 NOT NULL
.
你可以这样做:
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
?
解决方案
INNER JOIN
是您应该使用的ANSI语法。
通常认为它更具可读性,尤其是当您加入大量表格时。
只要有需要,也可以用OUTER JOIN
轻松替换。
WHERE
语法更加面向关系模型。
两个表的结果JOIN
ed是应用过滤器的表的笛卡尔积,它只选择那些具有连接列匹配的行。
使用STRAIGHT_JOIN
语法更容易看到这一点。
至于你的例子,在MySQL(以及一般的SQL)中,这两个查询是同义词。
另请注意,MySQL也有一个<=>子句。
使用此子句,您可以控制<=>顺序:在外循环中扫描哪个表以及哪个表在内循环中。
您无法使用<=>语法在MySQL中控制此操作。
其他提示
其他人指出,INNER JOIN有助于人类的可读性,这是首要任务;我同意。让我试着解释为什么连接语法更具可读性。
基本的SELECT查询是:
SELECT stuff
FROM tables
WHERE conditions
SELECT子句告诉我们我们要回来的; FROM子句告诉我们 where 我们从中得到它,而WHERE子句告诉我们我们得到的。
JOIN是关于表的声明,它们是如何绑定在一起的(从概念上讲,实际上是绑定在一个表中)。控制表的任何查询元素 - 我们从中获取东西 - 在语义上属于FROM子句(当然,这是JOIN元素所在的位置)。将join-elements放入WHERE子句会将哪个和 where-from 混为一谈。这就是首选JOIN语法的原因。
在ON / WHERE中应用条件语句
这里我已经解释了逻辑查询处理步骤。
参考:微软内部<!>#174; SQL Server <!>#8482; 2005 T-SQL查询
出版商:Microsoft Press
发布日期:2006年3月7日
打印ISBN-10:0-7356-2313-9
打印ISBN-13:978-0-7356-2313-2
页数:640
一旦您需要开始向查询添加更多表,隐式联接(这是您的第一个查询被称为)会变得更加混乱,难以阅读和难以维护。想象一下,在四个或五个不同的表上进行相同的查询和连接类型......这是一场噩梦。
使用显式连接(您的第二个示例)更易读且易于维护。
我还要指出,使用旧语法更容易出错。如果在没有ON子句的情况下使用内部联接,则会出现语法错误。如果您使用旧语法并忘记where子句中的一个连接条件,您将获得交叉连接。开发人员经常通过添加distinct关键字(而不是修复连接,因为他们仍然没有意识到连接本身被破坏)来解决这个问题,这似乎可以解决问题,但会大大减慢查询速度。
另外,对于维护,如果您使用旧语法进行交叉连接,维护者将如何知道您是否有一个(有需要交叉连接的情况)或者是否应该修复意外? / p>
让我指出这个问题,看看为什么如果你使用左连接,隐式语法是坏的。 Sybase * = to Ansi Standard有2个不同的外表用于相同的内表
Plus(个人咆哮),使用显式连接的标准已超过20年,这意味着隐式连接语法已经过时了20年。您是否会使用已经过时20年的语法编写应用程序代码?你为什么要编写数据库代码?
它们具有不同的人类可读意义。
但是,根据查询优化器,它们可能与计算机具有相同的含义。
您应始终编码以便可读。
也就是说,如果这是内置关系,请使用显式连接。如果要匹配弱相关数据,请使用where子句。
SQL:2003标准更改了一些优先规则,因此JOIN语句优先于<!>“逗号<!>”;加入。这实际上可以根据设置的方式更改查询结果。当MySQL 5.0.12切换到符合标准时,这会给某些人带来一些问题。
因此,在您的示例中,您的查询将起作用。但是如果你添加了第三个表: SELECT ... FROM table1,table2 JOIN table3 ON ... WHERE ...
在MySQL 5.0.12之前,首先连接table1和table2,然后连接table3。现在(5.0.12及以上),首先连接table2和table3,然后连接table1。它并不总能改变结果,但它可以,你甚至可能都没有意识到它。
我从不使用<!>“逗号<!>”;语法了,选择你的第二个例子。无论如何,它的可读性更高,JOIN条件与JOIN相关,而不是单独的查询部分。
我知道你在谈论MySQL,但无论如何: 在Oracle 9中,显式连接和隐式连接将生成不同的执行计划。已经在Oracle 10+中解决的AFAIK:再也没有这样的差异了。
ANSI连接语法肯定更具可移植性。
我正在进行Microsoft SQL Server的升级,我还要提到的是,对于2005 sql server及更高版本,不支持SQL Server中外连接的= *和* =语法(没有兼容模式)。