当我从多个表中选择数据时,我曾经经常使用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上这样做。
但是这两种方法有什么优缺点吗?
答案 0 :(得分:10)
第二种方法是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'形式的错误。有关处理此问题的信息将在本节后面给出。
一般来说,那里提到了很多东西,应该让你考虑不使用逗号。
答案 1 :(得分:3)
第一种方法是Join的ANSI / ISO版本。第二种方法是旧格式(pre-89),以产生内部连接的等价物。它通过交叉连接您列出的所有表格然后缩小Where子句中的笛卡尔积来生成内部联接的等价物来实现此目的。
我强烈建议不要使用第二种方法。
没有理由使用第二种格式,事实上许多数据库系统都在终止对该格式的支持。
答案 2 :(得分:2)
两个查询都是JOIN,并且都使用ANSI语法,但一个比另一个查询旧。
使用JOIN
关键字加入意味着正在使用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
的引用将为NULL在JOIN标准上(在ON
子句中指定)。第二个示例是INNER JOIN,它将 生成TABLE_2
中具有匹配记录的行。这是link to a visual representation of JOINs加强差异......
使用ANSI-92语法的主要原因是因为ANSI-89没有任何OUTER JOIN(LEFT,RIGHT,FULL)支持。 ANSI-92语法是专门为解决这个缺点而引入的,因为供应商正在实现他们自己的自定义语法。 Oracle使用(+)
; SQL Server在连接条件中使用等号旁边的星号(IE:t1.column =* t2.column
)。
使用ANSI-92语法的下一个原因是它更明确,更具可读性,同时将用于连接表的内容与实际过滤分开。
答案 3 :(得分:0)
我个人认为显式联接语法(A JOIN B
,A LEFT JOIN B
)更可取。两者都是因为它更清楚你正在做什么,并且因为如果你对内部联接使用隐式连接语法,你仍然必须使用外部联接的显式语法,因此你的SQL格式将是不一致的。
答案 4 :(得分:0)
我同意Mchl和Thomas在答案中所写的内容。我特别强调你应该避免使用第二个例子(通过WHERE
子句指定连接的地方),并选择更明确的JOIN ... ON
形式。
我正在为此辩护,因为显式版本(LEFT JOIN ... ON ... = ...
)还有另一个重要优势:您将连接规范与实际过滤条件明确分开(在JOIN ... ON
子句中)(在{ {1}}子句,使您的SQL代码更清晰,更易于理解。