当我从多个表中选择数据时,我常常使用JOINS,最近我开始使用另一种方式,但从长远来看,我不确定其影响。
例子:
SELECT * FROM table_1 LEFT JOIN table_2 ON (table_1.column = table_2.column)
所以这是跨表的基本LEFT JOIN,但请看下面的查询。
SELECT * FROM table_1,table_2 WHERE table_1.column = table_2.column
就个人而言,如果我加入,请说7个数据表我宁愿在JOINS上这样做。
但是这两种方法有什么优缺点吗?
第二种方法是INNER JOIN的快捷方式。
SELECT * FROM table_1 INNER JOIN table_2 ON table_1.column = table_2.column
只会选择与两个表中的条件匹配的记录(LEFT JOIN将从左侧的表中选择所有记录,并从右侧的表中选择匹配的记录)
引用自 http://dev.mysql.com/doc/refman/5.0/en/join.html
[...]我们将table_reference项列表中的每个逗号视为等同于内连接
和
在没有连接条件的情况下,INNER JOIN和(逗号)在语义上是等价的:两者在指定的表之间产生笛卡尔积(即,第一个表中的每一行都连接到第二个表中的每一行)。
但是,逗号运算符的优先级小于INNER JOIN,CROSS JOIN,LEFT JOIN等。如果在存在连接条件时将逗号连接与其他连接类型混合,则可能会出现'on子句'中未知列'col_name'形式的错误。有关处理此问题的信息将在本节后面给出。
一般来说,有很多提到的东西,应该让你考虑不使用逗号。
第二种方法是INNER JOIN的快捷方式。
SELECT * FROM table_1 INNER JOIN table_2 ON table_1.column = table_2.column
只会选择与两个表中的条件匹配的记录(LEFT JOIN将从左侧的表中选择所有记录,并从右侧的表中选择匹配的记录)
引用自 http://dev.mysql.com/doc/refman/5.0/en/join.html
[...]我们将table_reference项列表中的每个逗号视为等同于内连接
和
在没有连接条件的情况下,INNER JOIN和(逗号)在语义上是等价的:两者在指定的表之间产生笛卡尔积(即,第一个表中的每一行都连接到第二个表中的每一行)。
但是,逗号运算符的优先级小于INNER JOIN,CROSS JOIN,LEFT JOIN等。如果在存在连接条件时将逗号连接与其他连接类型混合,则可能会出现'on子句'中未知列'col_name'形式的错误。有关处理此问题的信息将在本节后面给出。
一般来说,有很多提到的东西,应该让你考虑不使用逗号。
第一种方法是Join的ANSI / ISO版本。第二种方法是旧格式(pre-89),以产生内部连接的等价物。它通过交叉连接您列出的所有表,然后在Where子句中缩小笛卡尔积来生成等效的内连接。
我强烈建议不要使用第二种方法。
- 其他开发人员更难阅读
- 它打破了其他开发人员最不惊讶的规则,他们会怀疑你是否只是不知道更好,或者是否有某些特定原因不使用ANSI / ISO格式。
- 当你开始尝试使用除内连接之外的其他格式时,它会让你感到悲伤。
- 这使得识别您的意图变得更加困难,尤其是在具有许多表的大型查询中。所有这些表都应该是内连接吗?您是否错过了Where子句中的某些内容并创建了交叉连接?你打算交叉加入吗?等等。
没有理由使用第二种格式,事实上许多数据库系统正在终止对该格式的支持。
ANSI语法
两个查询都是JOIN,并且都使用ANSI语法,但一个比另一个查询旧。
加入使用 JOIN
keyword表示正在使用ANSI-92语法。 ANSI-89语法是指在表中以逗号分隔的表 FROM
子句,以及加入它们的标准可以在 WHERE
条款。比较INNER JOIN时,没有性能差异 - 这个:
SELECT *
FROM table_1 t1, table_2 t2
WHERE t1.column = t2.column
...将生成相同的查询计划:
SELECT *
FROM TABLE_1 t1
JOIN TABLE_2 t2 ON t2.column = t1.column
苹果到橘子
另一个区别是两个查询不相同 - LEFT [OUTER] JOIN将生成所有行 TABLE_1
和参考 TABLE_2
如果根据JOIN条件(在。中指定)没有匹配,则在输出中将为NULL ON
条款)。第二个例子是INNER JOIN,它会 只要 生成具有匹配记录的行 TABLE_2
。这是一个 链接到JOIN的可视化表示 加强差异......
优点缺点
使用ANSI-92语法的主要原因是因为ANSI-89没有任何OUTER JOIN(LEFT,RIGHT,FULL)支持。 ANSI-92语法是专门为解决这个缺点而引入的,因为供应商正在实现他们自己的自定义语法。 Oracle使用过 (+)
; SQL Server在连接条件中使用等号旁边的星号(IE: t1.column =* t2.column
)。
使用ANSI-92语法的下一个原因是它更明确,更具可读性,同时将用于连接表的内容与实际过滤分开。
我个人觉得显式连接语法(A JOIN B
, A LEFT JOIN B
)是优选的。两者都是因为它更清楚你正在做什么,并且因为如果你对内部联接使用隐式连接语法,你仍然必须使用外部联接的显式语法,因此你的SQL格式将是不一致的。
我同意Mchl和Thomas在答案中所写的内容。我特别强调你应该避免使用第二个例子(你通过它指定连接的地方) WHERE
条款)并且更明确 JOIN ... ON
形成。
我正在争论这个因为显式版本(LEFT JOIN ... ON ... = ...
)有另一个重要的优点:你有明确分开的连接规范(在 JOIN ... ON
从实际过滤条件(在 WHERE
()),使您的SQL代码更清晰,更易于理解。