We're trying to run an outer join between table A on both tables B and C but get the error:
ORA-01417: a table may be outer joined to at most one other table
How can we get this to work?
Query:
select a.xxx, a.yyy, b.col1, c.col1 from a, b, c
where
a.xxx = b.xxx (+) and
a.yyy = b.yyy (+) and
a.xxx = c.xxx (+) and
a.yyy = c.yyy (+)
Use proper explicit join syntax. I think the following is probably what you want to do:
select a.xxx, a.yyy, b.col1, c.col1
from a left join
b
on a.xxx = b.xxx and a.yyy = b.yyy left join
c
on a.xxx = c.xxx and a.yyy = c.yyy;
You could try:
select a.xxx, y.xxx, b.col1, c.col2
from a
left join b on a.xxx = b.xxx and a.yyy = b.yyy
left join c on a.xxx = c.xxx and a.yyy = c.yyy
Please refrain from using comma in the from clause and use the JOIN clause instead.
Try using this:
select a.xxx, a.yyy, b.col1, c.col1
from a LEFT JOIN b ON a.xxx = b.xxx AND a.yyy = b.yyy
LEFT JOIN c ON a.xxx = c.xxx AND a.yyy = c.yyy
Related
I'm wondering if I am using CTEs correctly. I have two versions of a query, the first one uses a CTE and the second one uses multiple joins, both accomplish the same result.
So, my question(s) is, am I using the CTE correctly? It is more readable, but was this the intended use/ is it more efficient than the joins?
CTE QUERY:
WITH ASSOCIATION AS (
SELECT PK_COLUMN AS ID,
ENTITY_COLUMN,
ANOTHER_ENTITY,
FROM A
LEFT OUTER JOIN B ON A.ID = B.ID
LEFT OUTER JOIN C ON C.ID = B.ID
LEFT OUTER JOIN D ON D.ID = C.ID
)
SELECT COLUMNS
FROM Z
LEFT JOIN Y ON Y.ID = Z.ID
LEFT JOIN ASSOCIATION AA ON AA.ID = Y.ID AND SOME_CONDITION
LEFT JOIN ASSOCIATION BB ON BB.ID = Y.ID AND SOME_DIFFERENT_CONDITION
vs
MULTIPLE JOINS QUERY:
SELECT COLUMNS
FROM Z
LEFT JOIN Y ON Y.ID = Z.ID
LEFT JOIN A ON A.ID = Y.ID AND SOME_CONDITION
LEFT JOIN B ON A.ID = B.ID
LEFT JOIN C ON C.ID = B.ID
LEFT JOIN D ON D.ID = C.ID
LEFT JOIN A A2 ON A2.ID ON Y.ID AND SOME_DIFFERENT_CONDITION
LEFT JOIN B B2 ON A2.ID = B2.ID
LEFT JOIN C C2 ON C2.ID = B2.ID
LEFT JOIN D D2 ON D2.ID = C2.ID
I have C table as Main Table, which is joining left join with E table on col3 and which is joining left join with F table on col4.
(
FROM A
LEFT OUTER JOIN B ON A.col1 = B.col1
LEFT OUTER JOIN C ON A.col2 = C.col2
LEFT OUTER JOIN E ON A.col3 = E.col3
LEFT OUTER JOIN F ON A.col4 = F.col4
)temptab1
Which needs to left join with
(
FROM C ON
LEFT OUTER JOIN E ON C.col3 = E.col3
LEFT OUTER JOIN F ON C.col4 = F.col4
)temptab2
Now, should i join temptab1 to temptab2 on (C.Col3 = temptab2.Col3 OR C.Col4 = temptab2.Col4) ? OR
should i join temptab1 to temptab2 on (C.Col3 = temptab2.Col3 AND C.Col4 = temptab2.Col4) ?
IF i have to use OR clause, it is hindering performance of the query a lot...
I tried using union clause instead of OR clause. Still, query performance is not improving...
Please suggest better query.
The temptab1 is all rows of A. The temptab2 is all rows of C. And the temptab1 is LEFT JOIN with temptab2, which results in all rows of A.
You may use CASE statements to identify the matching values across A, B, C, D, E, F and remove the Join with temptab2.
Apologies, could not comment...
I would like to convert the following Oracle SQL query syntax (Use LEFT OUTER JOIN instead of (+)):
SELECT *
FROM TABLEA A, TABLEB B, TABLEC C, TABLED D
WHERE MY_COL = #col_val
AND A.X = B.X(+)
AND B.Y = C.Y(+)
AND D.Z=A.Z
Here is what I tried so far:
SELECT *
FROM TABLEA A, TABLEB B, TABLEC C, TABLED D
LEFT OUTER JOIN TABLEA A ON A.X = B.X
LEFT OUTER JOIN TABLEC C ON B.Y = C.Y
WHERE MY_COL = #col_val
AND D.Z = A.Z;
But I get the error :
"ORA-00904: "B"."X" : invalid identifier"
The join on D is an inner join, the rest are left outer joins:
SELECT *
FROM TABLEA A JOIN
TABLED D
ON D.Z = A.Z LEFT JOIN
TABLEB B
ON A.X = B.X LEFT JOIN
TABLEC C
ON B.Y = C.Y
WHERE MY_COL = #col_val;
I always start chains of joins with inner joins followed by the left outer join. I never use right join, and full join rather rarely. The inner joins define the rows in the result set, so they come first.
You don't should mix explicit and implicit sintax
SELECT *
FROM TABLEA A
INNER JOIN TABLEL L ON L.Z = A.Z
LEFT OUTER JOIN TABLEB B ON A.X = B.X
LEFT OUTER JOIN TABLEC C ON B.Y = C.Y
WHERE A.MY_COL = #col_val
you should use inner join (or join) for TABLEL
Try this:
SELECT *
FROM TABLEA A
LEFT OUTER JOIN TABLEB B ON A.X = B.X
LEFT OUTER JOIN TABLEC C ON B.Y = C.Y
INNER JOIN TABLED D ON D.Z = A.Z
WHERE MY_COL = #col_val
TABLEB and TABLEC goes in LEFT OUTER JOIN (you have used +), instead TABLED goes in INNER JOIN
Is it valid to combine Oracle inner and outer joins in the same query a la:
select b.col1, c.col2, sum(d.col1), sum(e.col1) from
a
inner join b on a.xxx = b.xxx
inner join c on a.yyy = c.yyy
left join d on b.aaa = d.aaa and c.bbb = d.bbb
left join e on b.aaa = e.bbb and c.aaa = e.bbb
group by b.col1, c.col2
Yes, you can combine inner, left and right joins the way you deem fit in the query. Just make sure that you understand the implications of inner, left and outer joins. Couple of blogs describe joins nicely: http://blog.codinghorror.com/a-visual-explanation-of-sql-joins/ and http://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins
The outer join nulls are ignored in your sum(d.col1) and sum(e.col1) values.
Why SUM(null) is not 0 in Oracle?
If alternate default values are needed for your null outer join results, consider NVL and similar.
Sum columns with null values in oracle
Please try this, All non aggregated columns should be in group by clause.
select b.col1, c.col2, sum(d.col1), sum(e.col1) from
a
inner join b on a.xxx = b.xxx
inner join c on a.yyy = c.yyy
left join d on b.aaa = d.aaa and c.bbb = d.bbb
left join e on b.aaa = e.bbb and c.aaa = e.bbb
group by b.col1, c.col2
What is the correct syntax to perform an outer join with the following requirements:
A left outer join B on A.c1 = B.c1
B left outer join C on B.c2 = C.c2
A left outer join D on A.c1 = D.c1
So A, B, and C cascade and A and D cascade.
I know how to write the A->B->C but I don't know how to add D. I need scope or parenthesis or something.
this should work as you want:
SELECT
*
FROM A
left outer join B on A.c1 = B.c1
left outer join C on B.c2 = C.c2
left outer join D on A.c1 = D.c1
the DB engine looks at what your are joining to, not the order of the joins. D joins to A, and has nothing to do with B or C
The order in which you join doesn't matter, the database will build a result set of every combination of rows in all tables, limited by the on clause. For example, because 1=1 is always true, this would give you 1000 rows:
select *
from ten_row_table A
left join ten_row_table B on 1=1
left join ten_row_table C on 1=1
But this would give you 10 rows:
select *
from ten_row_table A
left join ten_row_table B on A.id = B.id
left join ten_row_table C on A.id = C.id
You can make complicated queries slightly more readable by indentation. We indent second and further dependencies by four spaces, like:
from A
left outer join B on A.c1 = B.c1
left outer join C on B.c2 = C.c2
left outer join D on C.c3 = D.c3
left outer join E on B.c2 = E.c2
left outer join F on A.c1 = F.c1