我有三张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)
- 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子句的第二个连接应该不会有问题(不明确的事情)。
那么,第一个查询的问题在哪里呢?
2条答案
按热度按时间mpgws1up1#
如果只使用第一个连接,则会看到明显的区别
因此,关键是在使用
ON condition
时,select *
返回 * 两个表中的所有列 * -这就导致了您的问题。与
USING column
的连接只返回一次 using columns--不幸的是,我找不到有关此行为的文档,最接近的描述是在使用USING子句的外部联接中,查询返回单个列,该列合并联接中的两个匹配列。
6kkfgxo02#
如果我理解得很好,在第一个查询中,3列SAMECOLX使用别名(如SAMECOL1_1、SAMECOL2_1、SAMECOL3_1)重命名
不可以。连接操作不会重命名列。如果您使用该连接只查询了这两个表,那么您的客户端在显示结果时会选择添加
_1
部分;它不是结果集的一部分。您所看到的内容取决于您的客户端以及您运行它的方式。例如,如果您将其作为查询运行(run语句或control-enter),则SQL Developer将按照您在“查询结果”窗口中所描述的那样更改列标题;但如果将其作为脚本运行(run script或F5),则它不会在“脚本输出”窗口中执行此操作。SQL*Plus或SQLcl也不会执行此操作。
所以第一部分
有效地使两个表中的所有列都可用于以后的处理,包括仍称为
SAMECOL1
的两列,然后是下一部分不知道您指的是这两列中的哪一列-它无法区分
Table1.SAMECOL1
和Table2.SAMECOL2
。* 您 * 知道它们是相同的数据,但查询中没有任何内容表明是这种情况。在第二种形式中,第一个
USING
消除了这种歧义:只有一个
SAMECOL1
投影-这是一种来自两个源表或没有来自任何一个源表。您可以看到in this fiddle的不同之处,它 * 不 * 像您假设的那样(也像您的客户端那样)为第一个查询中的重复列取别名:
| 我的主键列|沙门氏菌1|SAMECOL2|样本3|我的主键列|沙门氏菌1|SAMECOL2|样本3|
| - ------|- ------|- ------|- ------|- ------|- ------|- ------|- ------|
| 四十二|1个|第二章|三个|四十二|1个|第二章|三个|
| 我的主键列|沙门氏菌1|SAMECOL2|样本3|
| - ------|- ------|- ------|- ------|
| 四十二|1个|第二章|三个|