Reputation: 369
I have 3 tables : Table1, Table2 and Table3. The three tables contains 3 same columns SAMECOL1, SAMECOL2 and SAMECOL3. Both tables Table1 and Table2 have the MY_PK_COL column which is the primary key of the Table1.
When I use this query in SQL Developer I get an error :
SELECT * FROM Table1
INNER JOIN Table2 ON Table1.MY_PK_COL = Table2.MY_PK_COL
JOIN Table3 USING (SAMECOL1, SAMECOL2, SAMECOL3)
- 00000 - "column ambiguously defined"
But when I use this it's ok :
SELECT * FROM Table1
JOIN Table2 USING (MY_PK_COL, SAMECOL1, SAMECOL2, SAMECOL3)
JOIN Table3 USING (SAMECOL1, SAMECOL2, SAMECOL3)
If I understand well, in the first query the 3 columns SAMECOLx are renamed with aliases such as SAMECOL1_1, SAMECOL2_1, SAMECOL3_1 so it should not be a problem for the second join with the USING clause (ambiguous thing).
So, where is the problem with the first query ?
Upvotes: 1
Views: 78
Reputation: 21063
If you use only the first join you see the obvious difference
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
So the point is while using the ON condition
the select *
returns all columns from both tables - which leads to your problem.
Join with USING column
returns the using columns only once - unfortunately I can't find a documentation of this behavior, the closest description is
In an outer join with the USING clause, the query returns a single column that coalesces the two matching columns in the join.
Upvotes: 2
Reputation: 191245
If I understand well, in the first query the 3 columns SAMECOLx are renamed with aliases such as SAMECOL1_1, SAMECOL2_1, SAMECOL3_1
No. The join operation does not rename the columns. If you queried just those two tables, with that join, then your client is choosing to add the _1
part when it displays the results; it isn't part of the result set.
What you see depends on your client and how you run it. For example, SQL Developer will change the column headings as you describe in the 'Query Result' window if you run it as a query (run statement, or control-enter); but if you run it as a script (run script, or F5) then it doesn't do that in the 'Script Output' window. Neither does SQL*Plus, or SQLcl.
So the first part
Table1
INNER JOIN Table2 ON Table1.MY_PK_COL = Table2.MY_PK_COL
effectively makes all of the columns from both tables available for later processing, including two columns still called SAMECOL1
, and then the next part
JOIN Table3 USING (SAMECOL1, SAMECOL2, SAMECOL3)
doesn't know which of the two columns you mean - it can't distinguish between Table1.SAMECOL1
and Table2.SAMECOL2
. You know they are the same data, but there is nothing in the query that says that is the case.
In the second form the first USING
eliminates that ambiguity:
Table1
JOIN Table2 USING (MY_PK_COL, SAMECOL1, SAMECOL2, SAMECOL3)
only has a single SAMECOL1
projected - which is kind of from both and neither of the source tables.
You can see the difference in this fiddle, which does not alias the duplicate columns in the first query as you assumed (and as your client does):
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 |
---|---|---|---|---|---|---|---|
42 | 1 | 2 | 3 | 42 | 1 | 2 | 3 |
SELECT * FROM Table1
JOIN Table2 USING (MY_PK_COL, SAMECOL1, SAMECOL2, SAMECOL3)
MY_PK_COL | SAMECOL1 | SAMECOL2 | SAMECOL3 |
---|---|---|---|
42 | 1 | 2 | 3 |
Upvotes: 1