有一个查询使用相同的别名(但在不同的条件下)两次连接同一个表。随后将引用这两个数据集中的哪一个别名点?
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中两次引用别名时应该使用哪个别名呢?
如果为列提供明确的标识符,那么表别名将引用与具有适当列标识符的表(或内联视图)相对应的别名。例如,如果您有示例数据:
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
表别名的第一个实例。