Outer join differences
Hi,
I see different results in Oracle and postgres for same outer join queries.
Here are the details.
I have the following tables in our pg db
table: yuva_test1
yt1_id yt1_name yt1_descr
1 1-name1 1-desc1
2 1-name2 1-desc2
3 1-name3 1-desc3
4 1-name4 1-desc4
5 1-name5 1-desc5
6 1-name6 1-desc6
table: yuva_test2
yt2_id yt2_name yt2_descr
2 2-name2 2-desc2
3 2-name3 2-desc3
4 2-name4 2-desc4
When I run the query "select yt1_name, yt1_descr, yt2_name, yt2_descr from
yuva_test1 left outer join yuva_test2 on yt1_id=yt2_id and yt2_name =
'2-name2'" on postgres database I get the following results
yt1_name yt1_descr yt2_name yt2_descr
1-name1 1-descr1
1-name2 1-descr2 2-name2 2-descr2
1-name3 1-descr3
1-name4 1-descr4
1-name5 1-descr5
1-name6 1-descr6
But when I tried the same on Oracle(8.1.7) (the query is "select yt1_name,
yt1_descr, yt2_name, yt2_descr from yuva_test1, yuva_test2 where
yt1_id=yt2_id(+) and yt2_name = '2-name2'') I get the following results
yt1_name yt1_descr yt2_name yt2_descr
1-name2 1-descr2 2-name2 2-descr2
Why postgres is giving? which is standard? is it a bug? or is it the way
postgres is implemented? Could some one help me?
Note: at the end of my mail is script to create tables and data in postgres.
Thanks
Yuva
Sr. Java Developer
www.ebates.com
============================================================
Scripts:
CREATE TABLE "yuva_test1" (
"yt1_id" numeric(16, 0),
"yt1_name" varchar(16) NOT NULL,
"yt1_descr" varchar(32)
) WITH OIDS;
CREATE TABLE "yuva_test2" (
"yt2_id" numeric(16, 0),
"yt2_name" varchar(16) NOT NULL,
"yt2_descr" varchar(32)
) WITH OIDS;
insert into yuva_test1 (yt1_id, yt1_name, yt1_descr) values (1, '1-name1',
'1-descr1');
insert into yuva_test1 (yt1_id, yt1_name, yt1_descr) values (2, '1-name2',
'1-descr2');
insert into yuva_test1 (yt1_id, yt1_name, yt1_descr) values (3, '1-name3',
'1-descr3');
insert into yuva_test1 (yt1_id, yt1_name, yt1_descr) values (4, '1-name4',
'1-descr4');
insert into yuva_test1 (yt1_id, yt1_name, yt1_descr) values (5, '1-name5',
'1-descr5');
insert into yuva_test1 (yt1_id, yt1_name, yt1_descr) values (6, '1-name6',
'1-descr6');
insert into yuva_test2 (yt2_id, yt2_name, yt2_descr) values (2, '2-name2',
'2-descr2');
insert into yuva_test2 (yt2_id, yt2_name, yt2_descr) values (3, '2-name3',
'2-descr3');
insert into yuva_test2 (yt2_id, yt2_name, yt2_descr) values (4, '2-name4',
'2-descr4');
============================================================
Yuva Chandolu <ychandolu@ebates.com> writes:
I see different results in Oracle and postgres for same outer join queries.
I believe you are sending your bug report to the wrong database.
When I run the query "select yt1_name, yt1_descr, yt2_name, yt2_descr from
yuva_test1 left outer join yuva_test2 on yt1_id=yt2_id and yt2_name =
'2-name2'" on postgres database I get the following results
yt1_name yt1_descr yt2_name yt2_descr
1-name1 1-descr1
1-name2 1-descr2 2-name2 2-descr2
1-name3 1-descr3
1-name4 1-descr4
1-name5 1-descr5
1-name6 1-descr6
But when I tried the same on Oracle(8.1.7) (the query is "select yt1_name,
yt1_descr, yt2_name, yt2_descr from yuva_test1, yuva_test2 where
yt1_id=yt2_id(+) and yt2_name = '2-name2'') I get the following results
yt1_name yt1_descr yt2_name yt2_descr
1-name2 1-descr2 2-name2 2-descr2
According to the SQL spec, the output of a LEFT JOIN consists of those
joined rows where the join condition is true, plus those rows of the
left table for which no right-table row produced a true join condition
(substituting nulls for the right-table columns). Our output clearly
conforms to the spec.
I do not know what Oracle thinks is the correct output when one
condition is marked with (+) and the other is not --- it's not very
obvious what that corresponds to in the spec's terminology. But I
suggest you take it up with them, not us.
regards, tom lane
Hi Tom,
Thanks for your prompt reply, after second thought(before receiving your
reply) I realized that postgres is doing more logically - i.e if the outer
join condition returns false then replace by nulls for right table columns.
We may change our code accordingly :-(.
Thanks
Yuva
-----Original Message-----
From: Tom Lane [mailto:tgl@sss.pgh.pa.us]
Sent: Tuesday, July 30, 2002 9:15 PM
To: Yuva Chandolu
Cc: 'pgsql-hackers@postgresql.org'
Subject: Re: [HACKERS] Outer join differences
Yuva Chandolu <ychandolu@ebates.com> writes:
I see different results in Oracle and postgres for same outer join
queries.
I believe you are sending your bug report to the wrong database.
When I run the query "select yt1_name, yt1_descr, yt2_name, yt2_descr from
yuva_test1 left outer join yuva_test2 on yt1_id=yt2_id and yt2_name =
'2-name2'" on postgres database I get the following results
yt1_name yt1_descr yt2_name yt2_descr
1-name1 1-descr1
1-name2 1-descr2 2-name2 2-descr2
1-name3 1-descr3
1-name4 1-descr4
1-name5 1-descr5
1-name6 1-descr6
But when I tried the same on Oracle(8.1.7) (the query is "select yt1_name,
yt1_descr, yt2_name, yt2_descr from yuva_test1, yuva_test2 where
yt1_id=yt2_id(+) and yt2_name = '2-name2'') I get the following results
yt1_name yt1_descr yt2_name yt2_descr
1-name2 1-descr2 2-name2 2-descr2
According to the SQL spec, the output of a LEFT JOIN consists of those
joined rows where the join condition is true, plus those rows of the
left table for which no right-table row produced a true join condition
(substituting nulls for the right-table columns). Our output clearly
conforms to the spec.
I do not know what Oracle thinks is the correct output when one
condition is marked with (+) and the other is not --- it's not very
obvious what that corresponds to in the spec's terminology. But I
suggest you take it up with them, not us.
regards, tom lane
Import Notes
Resolved by subject fallback
On Tue, 30 Jul 2002, Yuva Chandolu wrote:
Hi,
I see different results in Oracle and postgres for same outer join queries.
Here are the details.
Those probably aren't the same outer join queries.
When I run the query "select yt1_name, yt1_descr, yt2_name, yt2_descr from
yuva_test1 left outer join yuva_test2 on yt1_id=yt2_id and yt2_name =
'2-name2'" on postgres database I get the following results
Both conditions are part of the join condition for the outer join.
But when I tried the same on Oracle(8.1.7) (the query is "select yt1_name,
yt1_descr, yt2_name, yt2_descr from yuva_test1, yuva_test2 where
yt1_id=yt2_id(+) and yt2_name = '2-name2'') I get the following result
One condition is the join condition and one is a general where condition I
would guess since only one has the (+)
I think the equivalent query is
select yt1_name, yt1_descr, yt2_name, yt2_descr from yuva_test1 left outer
join yuva_test2 on yt1_id=yt2_id where yt2_name='2-name2'.
Note of course that you're destroying the outer joinness by doing
that yt2_name='2-name2' since the rows with no matching yuva_test2
will not match that conditoin.
When I run the query "select yt1_name, yt1_descr, yt2_name,
yt2_descr from
yuva_test1 left outer join yuva_test2 on yt1_id=yt2_id and yt2_name =
'2-name2'" on postgres database I get the following results
Probaly if you change your postgres query to this, it will give the same
answer as Oracle:
select yt1_name, yt1_descr, yt2_name,
yt2_descr from
yuva_test1 left outer join yuva_test2 on yt1_id=yt2_id where yt2_name =
'2-name2';
??
Chris
But when I tried the same on Oracle(8.1.7) (the query is
"select yt1_name,
yt1_descr, yt2_name, yt2_descr from yuva_test1, yuva_test2 where
yt1_id=yt2_id(+) and yt2_name = '2-name2'') I get the following result
And maybe if you change the oracle query to this, it will give the same
answer as postgres:
select yt1_name,
yt1_descr, yt2_name, yt2_descr from yuva_test1, yuva_test2 where
yt1_id=yt2_id(+) and yt2_name = '2-name2'(+);
Just guessing tho.
Chris
This is great, we thought we may go for code changes, we will go with this
solution instead.
Thanks
Yuva
-----Original Message-----
From: Stephan Szabo [mailto:sszabo@megazone23.bigpanda.com]
Sent: Tuesday, July 30, 2002 9:31 PM
To: Yuva Chandolu
Cc: 'pgsql-hackers@postgresql.org'
Subject: Re: [HACKERS] Outer join differences
On Tue, 30 Jul 2002, Yuva Chandolu wrote:
Hi,
I see different results in Oracle and postgres for same outer join
queries.
Here are the details.
Those probably aren't the same outer join queries.
When I run the query "select yt1_name, yt1_descr, yt2_name, yt2_descr from
yuva_test1 left outer join yuva_test2 on yt1_id=yt2_id and yt2_name =
'2-name2'" on postgres database I get the following results
Both conditions are part of the join condition for the outer join.
But when I tried the same on Oracle(8.1.7) (the query is "select yt1_name,
yt1_descr, yt2_name, yt2_descr from yuva_test1, yuva_test2 where
yt1_id=yt2_id(+) and yt2_name = '2-name2'') I get the following result
One condition is the join condition and one is a general where condition I
would guess since only one has the (+)
I think the equivalent query is
select yt1_name, yt1_descr, yt2_name, yt2_descr from yuva_test1 left outer
join yuva_test2 on yt1_id=yt2_id where yt2_name='2-name2'.
Note of course that you're destroying the outer joinness by doing
that yt2_name='2-name2' since the rows with no matching yuva_test2
will not match that conditoin.
Import Notes
Resolved by subject fallback
This is great, we thought we may go for code changes, we will go with this
solution instead.
But you did catch Stephan's point that an outer join is not required to
produce the result you apparently want? The equivalent inner join will
be at worst just as fast, and possibly faster, both for PostgreSQL and
for Oracle...
- Thomas
Here are the details.
Those probably aren't the same outer join queries.
I think you're right, these aren't the same, see below:
When I run the query "select yt1_name, yt1_descr, yt2_name, yt2_descr
from yuva_test1 left outer join yuva_test2 on yt1_id=yt2_id and yt2_name
= '2-name2'" on postgres database I get the following resultsBoth conditions are part of the join condition for the outer join.
But when I tried the same on Oracle(8.1.7) (the query is "select
yt1_name, yt1_descr, yt2_name, yt2_descr from yuva_test1, yuva_test2
where yt1_id=yt2_id(+) and yt2_name = '2-name2'') I get the following
result
I think for Oracle the equivalent is:
select yt1_name,
yt1_descr,
yt2_name,
yt2_descr
from yuva_test1,
yuva_test2
where yt2_id (+)= yt1_id=yt2_id
and yt2_name (+)= '2-name2'
Yuva,
The results make sense to me. The left outer join functionality in Postgres
is explained as follows:
LEFT OUTER JOIN returns all rows in the qualified Cartesian product (i.e.,
all combined rows that pass its ON condition), plus one copy of each row in
the left-hand table for which there was no right-hand row that passed the ON
condition. This left-hand row is extended to the full width of the joined
table by inserting NULLs for the right-hand columns. Note that only the
JOIN's own ON or USING condition is considered while deciding which rows
have matches. Outer ON or WHERE conditions are applied afterwards.
So, in your postgres statement, you are retrieving all rows from yuva_test1,
and the one row from yuva_test2 that satisfied the "where" criteria that
yt2_name = '2-name2'.
In Oracle, though, since your outer join is on yuva_test2, you would need
to specify an outer join on the criterion "yt2_name = '2-name2''" by saying
"yt2_name (+) = '2-name2''" to limit the resultset.
Hope this helps
Jill
Show quoted text
-----Original Message-----
From: Yuva Chandolu
Sent: Tuesday, July 30, 2002 8:53 PM
To: 'pgsql-hackers@postgresql.org'
Subject: Outer join differencesHi,
I see different results in Oracle and postgres for same outer join
queries. Here are the details.I have the following tables in our pg db
table: yuva_test1
yt1_id yt1_name yt1_descr
1 1-name1 1-desc1
2 1-name2 1-desc2
3 1-name3 1-desc3
4 1-name4 1-desc4
5 1-name5 1-desc5
6 1-name6 1-desc6table: yuva_test2
yt2_id yt2_name yt2_descr
2 2-name2 2-desc2
3 2-name3 2-desc3
4 2-name4 2-desc4When I run the query "select yt1_name, yt1_descr, yt2_name, yt2_descr from
yuva_test1 left outer join yuva_test2 on yt1_id=yt2_id and yt2_name =
'2-name2'" on postgres database I get the following resultsyt1_name yt1_descr yt2_name yt2_descr
1-name1 1-descr1
1-name2 1-descr2 2-name2 2-descr2
1-name3 1-descr3
1-name4 1-descr4
1-name5 1-descr5
1-name6 1-descr6But when I tried the same on Oracle(8.1.7) (the query is "select yt1_name,
yt1_descr, yt2_name, yt2_descr from yuva_test1, yuva_test2 where
yt1_id=yt2_id(+) and yt2_name = '2-name2'') I get the following resultsyt1_name yt1_descr yt2_name yt2_descr
1-name2 1-descr2 2-name2 2-descr2Why postgres is giving? which is standard? is it a bug? or is it the way
postgres is implemented? Could some one help me?Note: at the end of my mail is script to create tables and data in
postgres.Thanks
Yuva
Sr. Java Developer
www.ebates.com============================================================
Scripts:
CREATE TABLE "yuva_test1" (
"yt1_id" numeric(16, 0),
"yt1_name" varchar(16) NOT NULL,
"yt1_descr" varchar(32)
) WITH OIDS;CREATE TABLE "yuva_test2" (
"yt2_id" numeric(16, 0),
"yt2_name" varchar(16) NOT NULL,
"yt2_descr" varchar(32)
) WITH OIDS;insert into yuva_test1 (yt1_id, yt1_name, yt1_descr) values (1, '1-name1',
'1-descr1');
insert into yuva_test1 (yt1_id, yt1_name, yt1_descr) values (2, '1-name2',
'1-descr2');
insert into yuva_test1 (yt1_id, yt1_name, yt1_descr) values (3, '1-name3',
'1-descr3');
insert into yuva_test1 (yt1_id, yt1_name, yt1_descr) values (4, '1-name4',
'1-descr4');
insert into yuva_test1 (yt1_id, yt1_name, yt1_descr) values (5, '1-name5',
'1-descr5');
insert into yuva_test1 (yt1_id, yt1_name, yt1_descr) values (6, '1-name6',
'1-descr6');insert into yuva_test2 (yt2_id, yt2_name, yt2_descr) values (2, '2-name2',
'2-descr2');
insert into yuva_test2 (yt2_id, yt2_name, yt2_descr) values (3, '2-name3',
'2-descr3');
insert into yuva_test2 (yt2_id, yt2_name, yt2_descr) values (4, '2-name4',
'2-descr4');
============================================================
Import Notes
Resolved by subject fallback