同一个别名使用两次时,后续引用将指向哪一个?

问题描述 投票:0回答:1

有一个查询使用相同的别名(但在不同的条件下)两次连接同一个表。随后将引用这两个数据集中的哪一个别名点?

SELECT ...
  FROM table_1
  JOIN table_2 A ON ...
  JOIN table_3 A ON ...
  JOIN table_4 B ON A.col_1 = B.col_1

我使用以下查询进行了一个简单的实验:

  WITH
    test_1 AS (SELECT 1 AS col_1 FROM dual UNION ALL SELECT 2 AS col_1 FROM dual)
  , test_2 AS (SELECT 2 AS col_1 FROM dual UNION ALL SELECT 3 AS col_1 FROM dual)
  , test_3 AS (SELECT 1 AS col_1 FROM dual UNION ALL SELECT 2 AS col_1 FROM dual)
  , test_4 AS (SELECT 1 AS col_1 FROM dual UNION ALL SELECT 2 AS col_1 FROM dual)
SELECT *
  FROM test_1 b
  LEFT JOIN test_2 a ON a.col_1 = b.col_1
  LEFT JOIN test_3 a ON a.col_1 = b.col_1
  LEFT JOIN test_4 c ON a.col_1 = c.col_1;

结果:

col_1 col_1 col_1 col_1
1 1
2 2 2 2

建议表 test_4 的联接与别名的第一次出现相关联。同时,所有聊天机器人都确信应该使用最后提到的别名。因此,需要一个“刻在石头上”的规则来证明错误修复的合理性(因为实验可能无法涵盖所有可能的行为场景)。那么,根据“规则”,Oracle中两次引用别名时应该使用哪个别名呢?

sql oracle oracle12c
1个回答
0
投票

如果为列提供明确的标识符,那么表别名将引用与具有适当列标识符的表(或内联视图)相对应的别名。例如,如果您有示例数据:

CREATE TABLE test_1 (col_1) AS
SELECT 1 FROM DUAL UNION ALL
SELECT 2 FROM DUAL UNION ALL
SELECT 3 FROM DUAL UNION ALL
SELECT 4 FROM DUAL;

CREATE TABLE test_2 (col_2) AS
SELECT 2 FROM DUAL UNION ALL
SELECT 3 FROM DUAL;

CREATE TABLE test_3 (col_3) AS
SELECT 1 FROM DUAL UNION ALL
SELECT 4 FROM DUAL;

CREATE TABLE test_4 (col_4) AS
SELECT 1 FROM DUAL UNION ALL
SELECT 2 FROM DUAL UNION ALL
SELECT 3 FROM DUAL;

然后:

SELECT *
  FROM test_1 b
  LEFT JOIN test_2 a ON a.col_2 = b.col_1
  LEFT JOIN test_3 a ON a.col_3 = b.col_1
  LEFT JOIN test_4 c1 ON a.col_2 = c1.col_4
  LEFT JOIN test_4 c2 ON a.col_3 = c2.col_4;

等同于:

SELECT *
  FROM test_1 b
  LEFT JOIN test_2 a1 ON a1.col_2 = b.col_1
  LEFT JOIN test_3 a2 ON a2.col_3 = b.col_1
  LEFT JOIN test_4 c1 ON a1.col_2 = c1.col_4
  LEFT JOIN test_4 c2 ON a2.col_3 = c2.col_4;

并且两个输出:

COL_1 COL_2 COL_3 COL_4 COL_4
1 1 1
3 3 3
2 2 2
4 4

在这种情况下,使用的

a
别名取决于后续列标识符,并且
a.col_2
a.col_3
指不同的
a
别名。


如果您有不明确的列:

CREATE TABLE test_1 (col_1) AS
SELECT 1 FROM DUAL UNION ALL
SELECT 2 FROM DUAL UNION ALL
SELECT 3 FROM DUAL UNION ALL
SELECT 4 FROM DUAL;

CREATE TABLE test_2 (col_1) AS
SELECT 2 FROM DUAL UNION ALL
SELECT 3 FROM DUAL;

CREATE TABLE test_3 (col_1) AS
SELECT 1 FROM DUAL UNION ALL
SELECT 4 FROM DUAL;

CREATE TABLE test_4 (col_1) AS
SELECT 1 FROM DUAL UNION ALL
SELECT 2 FROM DUAL UNION ALL
SELECT 3 FROM DUAL;

然后查询:

SELECT *
  FROM test_1 b
  LEFT JOIN test_2 a ON a.col_1 = b.col_1
  LEFT JOIN test_3 a ON a.col_1 = b.col_1
  LEFT JOIN test_4 c ON a.col_1 = c.col_1;

等同于:

SELECT *
  FROM test_1 b
  LEFT JOIN test_2 a1 ON a1.col_1 = b.col_1
  LEFT JOIN test_3 a2 ON a2.col_1 = b.col_1
  LEFT JOIN test_4 c ON a1.col_1 = c.col_1;

并且两个输出:

COL_1 COL_1 COL_1 COL_1
2 2 2
3 3 3
4 4
1 1

其中

a.col_1
不明确,但似乎已解析为包含
a
列标识符的
col_1
表别名的第一个实例。

Oracle 小提琴:11gR2182123

© www.soinside.com 2019 - 2024. All rights reserved.