sql - 为什么 Oracle 不在这里抛出 "ambiguous column reference"?

标签 sql oracle

我在这里有几个 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
-- */
;

正如您在两个查询中看到的,表的别名 empemployment_type是相同的,即 e .

当我通过说 e.description 选择一列时我不应该得到一个错误说类似的话

ambiguous column reference



而且,两次查询的结果是不同的!首先,emp.description在第二个中被选中,employment_type.description被选中。

请让我知道为什么会发生这种情况以及如何避免由此引起的困惑。

最佳答案

Oracle SQL 从未完全符合任何 ANSI/ISO SQL 标准。
例如,它从不支持 ASfrom条款:

select *from dual AS d; -- fails

合规性的当前状态(Oracle Compliance To Core SQL:2011 对于 Oracle 12c)
表明 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 标准是否明确规定不允许在同一范围内使用重复的别名。
在 SQL:2011 标准的 SQL/Foundation 文档的第 2 部分的第 7.6 节中确实如此。 (您可以从 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),因此尽管来自草稿,但这些信息应该是准确的。

关于sql - 为什么 Oracle 不在这里抛出 "ambiguous column reference"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49510867/

相关文章:

mysql - 当条件没有为第二个表生成结果时,如何在 LEFT JOIN 上返回 NULL

mysql - 当表具有唯一值时查询显示重复项?

c# - 在数据库表中并发读取和更新

sql - 如何在plsql中的case语句中使用OR合并多个案例

oracle - 如何在开始后声明游标?

sql - 检查 SQL Server 中的重复数据

sql - 从日期时间中提取小时 (SQL Server 2005)

mysql - 查询未按预期运行

SQL - 使用 GROUP BY 时以逗号分隔的多个值

oracle - 如何将内联表作为参数发送到接收表的函数?