我在这里有几个SQL查询 -
WITH emp AS
(SELECT 1 AS empid, 'Adam' AS ename, 10 AS deptno, 'Broker' AS description FROM dual
UNION ALL
SELECT 2, 'Bob', 20, 'Accountant' FROM dual
UNION ALL
SELECT 3, 'Charles', 30, 'Programmer' FROM dual
UNION ALL
SELECT 4, 'Dan', 10, 'Manager' FROM dual
UNION ALL
SELECT 5, 'Eric', 10, 'Salesman' FROM dual
UNION ALL
SELECT 6, 'Franc', 20, 'Consultant' FROM dual),
dept AS
(SELECT 10 AS deptno, 'Accounts' AS dname, 100 employment_type_id FROM dual
UNION ALL
SELECT 20, 'Broking', 100 FROM dual
UNION ALL
SELECT 30, 'Corporate Relations', 200 FROM dual),
employment_type AS
(SELECT 100 AS employment_type_id, 'Permanent' AS description FROM dual
UNION ALL
SELECT 200, 'Contract' FROM dual)
/* --- Query 1
select e.ename, d.dname, e.description
from emp e
inner join dept d on e.deptno = d.deptno
inner join employment_type e on d.employment_type_id = e.employment_type_id
-- */
-- /* Query 2
SELECT e.ename, d.dname, e.description
FROM employment_type e
INNER JOIN dept d ON e.employment_type_id = d.employment_type_id
INNER JOIN emp e ON d.deptno = e.deptno
-- */
;
正如您在两个查询中看到的,表emp
和employment_type
的别名是相同的,即e
。
当我通过说e.description
选择列时,我不会收到类似
莫尔沃尔,两个查询的结果是不同的!在第一个中,模糊列参考
emp.description
被选中,而在第二个中,employment_type.description
被选中。
请让我知道为什么会发生这种情况,以及如何避免因此引起的混乱。
答案 0 :(得分:1)
Oracle SQL从未完全符合任何ANSI / ISO SQL标准。
例如,它从未支持AS
子句中的from
:
select *from dual AS d; -- fails
合规性的当前状态(Oracle {12 Oracle Compliance To Core SQL:2011) 表明ANSI SQL的各种功能主要部分支持,例如:
...
E031, Identifiers:
Oracle supports this feature, with the following exceptions:
...
或,
E051, Basic query specification
Oracle fully supports the following subfeatures:
...
虽然它没有说明含糊不清的别名(或范围变量正式),但您可以设想差异可以比页面中所述的更深入。
我目前知道在这种情况下无法使Oracle报告模糊,但仅仅注意使你的别名不同并不是我认为的那么难。
您可能想知道ANSI SQL Standard是否准确地说明不允许在同一范围内重复的别名。 它在第2部分的 7.6 部分中,SQL:Foundation 文档的SQL:2011标准。 (您可以从www.wiscorp.com下载草稿)。 具体来说,在语法规则,10)的小节中,它说(我把它剪了一下):
10) Let RV be a range variable that is exposed by TR. Let RV1 be a range variable that is exposed by a <table reference> TR1 that has the same scope clause as TR.
a) If RV is a <table name>, then
i) If RV1 is a <table name>, then RV1 shall not be equivalent to RV.
ii) Otherwise, RV1 shall not be equivalent to the <qualified identifier> of RV.
b) Otherwise
i) If RV1 is a <table name>, then the <qualified identifier> of RV1 shall not be equivalent to RV.
ii) Otherwise, RV1 shall not be equivalent to RV.
这里RV是可变范围,您可以看到最后一个选择适用于两个别名的情况。
我们知道主要的SQL品牌实施此检查(SQL Server,MySQL,PostgreSQL),因此这些信息应该是准确的,尽管来自草案。
答案 1 :(得分:0)
您可以尝试以下查询来获得结果:
这适用于:获取emp表描述
/* --- Query 1
select e.ename, d.dname, e.description
from emp e
inner join dept d on e.deptno = d.deptno
inner join employment_type et on d.employment_type_id = et.employment_type_id
-- */
-- /* Query 2
SELECT e.ename, d.dname, em.description
FROM employment_type e
INNER JOIN dept d ON e.employment_type_id = d.employment_type_id
INNER JOIN emp em ON d.deptno = em.deptno
-- */
根据你的代码:
您首先使用别名查询&#39; e&#39;对于emp表(作为第一个表)。 所以它从你指定的第一个表中获得描述(emp表)。
与查询2相同: 它参考表就业类型(作为第一表) 所以它得到了描述。