tags:

views:

219

answers:

6

Why wont this work in oracle?

is there a way to make this work?

FROM table1 a,
     table2 b,
     table3 c
WHERE a.some_id = '10'
AND a.other_id (+)= b.other_id
AND a.other_id (+)= c.other_id

I want table1 to be left outer joined on multiple tables...

If I try to change it to ANSI join I get compilation errors. I did the following:

FROM table2 b, table3 c
LEFT JOIN table1 a ON a.other_id = b.other_id and a.other_id = c.other_id
+4  A: 

use ansi joins. They are way clearer IMO. BUt for some reason they don't work with materialized views...

+1 - it is much clearer, but Oracle didn't support it until (I believe) 10g, so there's a lot of legacy code with the old syntax. And it's probably better to use consistent syntax.
kdgregory
@kdgregory: No, I used ANSI JOINs in 9i just fine.
OMG Ponies
A: 

In oracle you cannot outer join the same table to more than one other table. You can create views that have joins in them, then join to that view. As side note, you also cannot outer join to an sub select, so that is not an option here either.

northpole
+3  A: 

OK, looking at the examples from the Oracle docs, my recollection of the syntax was correct, so I'm turning my comment into an answer. Assuming that your goal is a left outer join where A is the base table, and you join matching rows from B and C, rewrite your query as follows (note that I'm just changing the prefixes; I like to have the source rowset on the right).

FROM table1 a,
     table2 b,
     table3 c
WHERE a.some_id = '10'
AND b.other_id (+)= a.other_id
AND c.other_id (+)= a.other_id

If that's not what you're trying to do, then the query is borked: you're doing a cartesian join of B and C, and then attempting an outer join from that partial result to A, with an additional predicate on A. Which doesn't make a lot of sense.

kdgregory
I want to clarify. I was under the impression that if (+) is on the right of some column then LEFT JOIN is on that table...am I wrong?Yes I want table1 a to be base table
Omnipresent
you're wrong - take a look at the examples link that I provided
kdgregory
so in this. left join is being done on a?? meaning we will get all rows of a
Omnipresent
the (+) is on the side, where no matching row might exist.
Juergen Hartelt
+1  A: 

You can do something like this.

FROM table1 a,     table2 b,     table3 c
WHERE a.some_id = '10'
AND a.other_id = b.other_id(+)
AND a.other_id = c.other_id(+)
Henry Gao
again, I think putting (+) on the right will make table2 and table3 the base tables. where as I want table1 a to be base
Omnipresent
no. the table1 is base in above query.
Henry Gao
Agreed. Since the original query has an equality condition on some_id in table1, it doesn't make any sense to outer-join table1 to other tables, which is what the original query was doing. Presumably what you want is to outer-join the other two tables to table1, which is what Henry's query does.
Dave Costa
I prefer to put the out join table on the right side to easy to catch
Henry Gao
+1  A: 

I wanted to address separately this part of your question:

If I try to change it to ANSI join I get compilation errors. I did the following:

FROM table2 b, table3 c
LEFT JOIN table1 a ON a.other_id = b.other_id and a.other_id = c.other_id

In an ANSI join, at least in Oracle, you are operating on exactly two row sources. The LEFT JOIN operator in your example has table3 and table1 as its operands; so you cannot reference "b.otherid" in the ON clause. You need a new join operator for each additional table.

I believe what you are trying to do is outer join table 2 and table 3 to table 1. So what you should be doing is this:

FROM table1 a LEFT JOIN table2 b ON b.other_id = a.other_id
              LEFT JOIN table3 c ON c.other_id = a.other_id

or Henry Gao's query if you want to use Oracle-specific syntax.

Dave Costa
A: 

You could off course try the following (Table b and c being the BASE) FROM (SELECT other_id FROM table2 UNION SELECT other_id FROM table3) b LEFT JOIN table1 a b.other_id = a.other_id

But then again I am an Oracle Nono

Jeroen