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_name
、employee_name
和company_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
表受到限制。
在SELECT
和WHERE
表达式中,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语句查询一个字段在另一表字段中有两条或以上 的数据