使用Oracle USING子句通过相同列连接两个以上的表

t1rydlwq  于 2023-02-11  发布在  Oracle
关注(0)|答案(2)|浏览(180)

我有三张table:表1、表2和表3。这三个表包含3个相同的列SAMECOL1、SAMECOL2和SAMECOL3。表1和表2都具有MY_PK_COL列,该列是表1的主键。
当我在SQL Developer中使用此查询时,收到一个错误:

SELECT * FROM Table1
INNER JOIN Table2 ON Table1.MY_PK_COL = Table2.MY_PK_COL 
JOIN Table3 USING (SAMECOL1, SAMECOL2, SAMECOL3)
  1. 00000-"列定义不明确"
    但当我使用这个时,它是可以的:
SELECT * FROM Table1
JOIN Table2 USING (MY_PK_COL, SAMECOL1, SAMECOL2, SAMECOL3)
JOIN Table3 USING (SAMECOL1, SAMECOL2, SAMECOL3)

如果我理解得很好,在第一个查询中,3列SAMECOLx使用别名(如SAMECOL1_1、SAMECOL2_1、SAMECOL3_1)重命名,因此使用USING子句的第二个连接应该不会有问题(不明确的事情)。
那么,第一个查询的问题在哪里呢?

mpgws1up

mpgws1up1#

如果只使用第一个连接,则会看到明显的区别

SELECT * FROM Table1
JOIN Table2 USING (MY_PK_COL, SAMECOL1, SAMECOL2, SAMECOL3);

 MY_PK_COL   SAMECOL1   SAMECOL2   SAMECOL3
---------- ---------- ---------- ----------
         1          1          1          1
         
SELECT * FROM Table1
INNER JOIN Table2 ON Table1.MY_PK_COL = Table2.MY_PK_COL;

 MY_PK_COL   SAMECOL1   SAMECOL2   SAMECOL3  MY_PK_COL   SAMECOL1   SAMECOL2   SAMECOL3
---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
         1          1          1          1          1          1          1          1

因此,关键是在使用ON condition时,select *返回 * 两个表中的所有列 * -这就导致了您的问题。
USING column的连接只返回一次 using columns--不幸的是,我找不到有关此行为的文档,最接近的描述是
在使用USING子句的外部联接中,查询返回单个列,该列合并联接中的两个匹配列。

6kkfgxo0

6kkfgxo02#

如果我理解得很好,在第一个查询中,3列SAMECOLX使用别名(如SAMECOL1_1、SAMECOL2_1、SAMECOL3_1)重命名
不可以。连接操作不会重命名列。如果您使用该连接只查询了这两个表,那么您的客户端在显示结果时会选择添加_1部分;它不是结果集的一部分。
您所看到的内容取决于您的客户端以及您运行它的方式。例如,如果您将其作为查询运行(run语句或control-enter),则SQL Developer将按照您在“查询结果”窗口中所描述的那样更改列标题;但如果将其作为脚本运行(run script或F5),则它不会在“脚本输出”窗口中执行此操作。SQL*Plus或SQLcl也不会执行此操作。
所以第一部分

Table1
INNER JOIN Table2 ON Table1.MY_PK_COL = Table2.MY_PK_COL

有效地使两个表中的所有列都可用于以后的处理,包括仍称为SAMECOL1的两列,然后是下一部分

JOIN Table3 USING (SAMECOL1, SAMECOL2, SAMECOL3)

不知道您指的是这两列中的哪一列-它无法区分Table1.SAMECOL1Table2.SAMECOL2。* 您 * 知道它们是相同的数据,但查询中没有任何内容表明是这种情况。
在第二种形式中,第一个USING消除了这种歧义:

Table1
JOIN Table2 USING (MY_PK_COL, SAMECOL1, SAMECOL2, SAMECOL3)

只有一个SAMECOL1投影-这是一种来自两个源表或没有来自任何一个源表。
您可以看到in this fiddle的不同之处,它 * 不 * 像您假设的那样(也像您的客户端那样)为第一个查询中的重复列取别名:

SELECT * FROM Table1
INNER JOIN Table2 ON Table1.MY_PK_COL = Table2.MY_PK_COL

| 我的主键列|沙门氏菌1|SAMECOL2|样本3|我的主键列|沙门氏菌1|SAMECOL2|样本3|
| - ------|- ------|- ------|- ------|- ------|- ------|- ------|- ------|
| 四十二|1个|第二章|三个|四十二|1个|第二章|三个|

SELECT * FROM Table1
JOIN Table2 USING (MY_PK_COL, SAMECOL1, SAMECOL2, SAMECOL3)

| 我的主键列|沙门氏菌1|SAMECOL2|样本3|
| - ------|- ------|- ------|- ------|
| 四十二|1个|第二章|三个|

相关问题