Oracle SQL 非唯一表别名在一个 Select 中

Posted

技术标签:

【中文标题】Oracle SQL 非唯一表别名在一个 Select 中【英文标题】:Oracle SQL non-unique table alias in one Select 【发布时间】:2013-11-27 15:36:27 【问题描述】:

有人知道为什么这对两个表别名“x”都有效吗?

Select x.company_name  
      ,x.employee_name 
FROM company  x
JOIN employee x ON x.company_id = 5

我知道 id 为 5 的 JOIN 没有意义...

谢谢你的课!

【问题讨论】:

company_id 是唯一的列吗? 感谢您的快速回答。在我看来,这没关系。我想知道为什么我可以使用相同的别名“x”两次。可以说,在公司上它是独一无二的,而在员工身上则不是。关系是“公司有很多员工”。 我的意思是,如果列名(company_nameemployee_namecompany_id)是唯一的,所以它们只存在于两个表之一中,别名无关紧要. 我编写了一个测试用例,其中两个表都有company_id 并且查询运行良好。如果我将 x.company_id 添加到 SELECT 子句中,我只会收到错误。 【参考方案1】:

我会在“Oracle 错误”上花钱 - 在所有最让我无法采用 ANSI JOIN 语法的事情中,这是 Oracle 令人痛苦的、令人震惊且充满错误的实现。也就是说,“未能捕获语法错误”是非常轻微的,据我所知,Oracle 已经在很大程度上清理了他们的行为。

【讨论】:

+1 对我来说也是一个错误。我在 My Oracle Support 上发现了一个相关的错误。这不是一回事,但它表明 Oracle 在不引发模棱两可的异常方面存在问题:“错误 5368296 - ANSI 连接 SQL 可能不会为模棱两可的列报告 ORA-918”。尽管即使有这些(罕见的)ANSI 语法错误,我认为 ANSI 语法仍然很值得。如果我能避免杂乱无章的 (+) 语法,我很乐意每年接受一次 Oracle 错误。 并非所有错误都是平等的。当 ANSI 连接的错误导致关键查询得到微妙的错误结果时,在通知前在生产环境中运行 2 周,并导致数据损坏需要 4 周的时间来清理......这不是世界上最好的感觉主张广泛采用更简洁的语法的人......【参考方案2】:

下面的前两个查询是等效的。在连接的ON 子句中,表别名x 仅指使用该别名的最后一个表,因此只有employee 表受到限制。

SELECTWHERE 表达式中,x 别名指的是这两个表 - 因此,如果列名是唯一的,那么它们可以被成功引用,但是如果列名相同,则 oracle 会引发 @987654331 @ 异常(如果评论被删除,则在查询 3 中发生)。

我找不到任何关于此的文档,但它看起来很像一个错误。

SQL Fiddle

Oracle 11g R2 架构设置

CREATE TABLE employee (
  company_id    NUMBER(3),
  employee_name VARCHAR2(20)
);

CREATE TABLE company (
  company_id    NUMBER(3),
  company_name VARCHAR2(20)
);

INSERT INTO employee VALUES ( 4, 'Four Emp' );
INSERT INTO employee VALUES ( 5, 'Five Emp' );
INSERT INTO employee VALUES ( 6, 'Six Emp' );

INSERT INTO company VALUES ( 4, 'Four Company' );
INSERT INTO company VALUES ( 5, 'Five Company' );
INSERT INTO company VALUES ( 6, 'Six Company' );

查询 1

SELECT *
FROM   company  x
       JOIN
       employee x
       ON x.company_id = 5

Results

| COMPANY_ID | COMPANY_NAME | EMPLOYEE_NAME |
|------------|--------------|---------------|
|          5 | Four Company |      Five Emp |
|          5 | Five Company |      Five Emp |
|          5 |  Six Company |      Five Emp |

查询 2

SELECT *
FROM   company x
       CROSS JOIN
       (SELECT * FROM employee WHERE company_id = 5) x

Results

| COMPANY_ID | COMPANY_NAME | EMPLOYEE_NAME |
|------------|--------------|---------------|
|          5 | Four Company |      Five Emp |
|          5 | Five Company |      Five Emp |
|          5 |  Six Company |      Five Emp |

查询 3

SELECT --x.company_id,
       x.company_name,
       x.employee_name
FROM   company x
       CROSS JOIN
       (SELECT * FROM employee WHERE company_id = 5) x

Results

| COMPANY_NAME | EMPLOYEE_NAME |
|--------------|---------------|
| Four Company |      Five Emp |
| Five Company |      Five Emp |
|  Six Company |      Five Emp |

【讨论】:

以上是关于Oracle SQL 非唯一表别名在一个 Select 中的主要内容,如果未能解决你的问题,请参考以下文章

如何解决ORACLE中表一得列名的别名为另一表中的某一字段的值?

ORACLE SQL语句查询一个字段在另一表字段中有两条或以上 的数据

ORACLE SQL语句查询一个字段在另一表字段中有两条或以上 的数据

求oracle中查询关联查询不同数据在另一表作为相同字段的对应的值

oracle的基础知识1

Oracle:更新非唯一字段