【问题标题】:Is the On Clause Neccessary for Left/Right Outer Joins左/右外部连接是否需要 On 子句
【发布时间】:2013-07-27 22:06:48
【问题描述】:

我在 MYSQL 中有以下非常简单的左外连接:

select * from employee left  join department

但是,这给了我毫无意义的错误信息

错误代码:1064。您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以获取正确的语法,以便在第 1 行的 '' 附近使用

但如果我只是添加一个如下所示的 ON 子句,则查询有效:

select * from employee left  join department on employee.departmentId = department.id;

那么,ON 子句是强制性的吗?如果我执行“完全连接”,它肯定可以在没有 ON 子句的情况下工作,但是左右外连接不起作用,除非我向它们添加 ON 子句。

顺便说一下,这两张表没有什么特别之处,它们之间也没有外键关系。

版本:

这是在 MySql 中工作的完整连接:

select * from employee full join department;

【问题讨论】:

  • Full outer 加入 do 需要 ON 子句。交叉连接没有。 (以及自然连接)
  • " 如果我​​执行“完全联接”,它肯定可以在没有 ON 子句的情况下工作" - 在 MySQL 中?真的吗??
  • 是的,这是一个有效的方法:select * from employee full join department;

标签: mysql sql oracle outer-join


【解决方案1】:

在 ANSI 标准中,除 cross join 之外的所有连接类型都需要 on。这适用于 Oracle 和大多数其他数据库。

MySQL 有点不同。这是MySQLdocumentation中的语法图:

join_table:
    table_reference [INNER | CROSS] JOIN table_factor [join_condition]
  | table_reference STRAIGHT_JOIN table_factor
  | table_reference STRAIGHT_JOIN table_factor ON conditional_expr
  | table_reference {LEFT|RIGHT} [OUTER] JOIN table_reference join_condition
  | table_reference NATURAL [{LEFT|RIGHT} [OUTER]] JOIN table_factor

也就是说,MySQL 允许onjoin 是可选的,但不允许left outer joinright outer join。 MySQL 不支持full outer join。而且,为了让cross join 更加混乱,就像join可以接受on 子句。

而且,您应该忽略 MySQL 扩展。 总是对左、右和内连接使用on 子句。 从不cross join 使用on 子句。我更喜欢使用这些而不是 natural join(你不会问),因为我更喜欢在用于连接的列中明确。

编辑:

根据SQL Fiddle,当left outer join 工作时,5.6 版在full outer join 上出现错误。所以这会产生一个错误:

select *
from (select 1 as a) t1 full outer join
     (select 2 as b) t2
     on t1.a = t2.b;

这也会产生错误:

select *
from (select 1 as a) t1 full join
     (select 2 as b) t2;

并且 MySQL 文档(通过 5.7)非常清楚不支持 full join。我不确定为什么您的查询可能有效。

【讨论】:

  • 感谢您提供清晰明了的解释。只是一个问题,您提到 MySQL 不支持完全外部联接,但这正如我上面提到的“从员工完全联接部门中选择 *”;这不是一个完整的外部连接吗?另外,我使用我认为是最新版本的 Mysql 5.6.10;所以他们可能最近添加了这个。
  • OP 的查询起作用的原因是因为他们只是将employee 表别名为full :-)
  • @Martin:很棒的收获。
【解决方案2】:

如果您希望它在没有 ON 子句的情况下工作,则需要在 2 个表中使用相同的列名: department.departmentId 与 employee.departmentId

【讨论】:

  • 我希望所有这些例外都不允许,因为它们只会让一切变得不必要地复杂化。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-04
  • 2014-02-24
  • 1970-01-01
  • 2011-02-25
  • 2011-04-22
相关资源
最近更新 更多