Reputation: 65
I'm using postgresql, though I confirmed this in sqlfiddle.com too.
My tables and elements are:
create table Publisher(pID int PRIMARY KEY, name varchar(255), address varchar(255));
create table Book(ISBN int PRIMARY KEY, name varchar(255), genre varchar(255), price int, copies int, pID int REFERENCES Publisher(pID));
insert into Publisher values(1, 'Oxford University Press', 'Senkosova');
insert into Book values(111, 'Alamut', 'Horror', 50, 100, 1);
I want to natural join Book and Publisher and get the books which is published by Oxford University Press.
This works:
select b.name
from Book as b, Publisher as p
where b.pid = p.pid and p.name ='Oxford University Press';
This does not:
select b.name
from Book as b natural join Publisher as p
where p.name = 'Oxford University Press';
Even this does not:
select *
from Book natural join Publisher;
Why??
Upvotes: 3
Views: 1091
Reputation: 1270301
Do not use natural join
, it is a bug waiting to happen. Instead, use an explicit on
or using
clause:
select b.name
from Book b join
Publisher p
using (pid)
where p.name = 'Oxford University Press';
or:
select b.name
from Book b join
Publisher p
where b.pid = p.pid
where p.name = 'Oxford University Press';
The problem with natural join
is two-fold. First, it bases the columns for comparisons on common names, not even on declared foreign key relationships. Both your tables have a name
column as well as an id
column, so at a minimum, the natural join query is equivalent to:
select b.name
from Book b join
Publisher p
where b.pid = p.pid and b.name = p.name
where p.name = 'Oxford University Press';
(And there might be other columns that have the same name.) I doubt any books are named 'Oxford University Press', so you have no matches in the data.
The second problem is related. By not including explicitly the columns used for joining, a reader of the query does not know. That makes the query harder to debug and understand. In my case, almost all tables that I create have CreatedAt
and CreatedBy
columns, so natural join
s would never work in my databases anyway.
Upvotes: 3
Reputation: 121754
You have more than one pair of columns with the same names in both tables: id
and name
. So
select *
from book
natural join publisher;
is equivalent to
select *
from book b
join publisher p on b.pid = p.pid
and b.name = p.name;
NATURAL is a shorthand form of USING: it forms a USING list consisting of all column names that appear in both input tables. As with USING, these columns appear only once in the output table. If there are no common column names, NATURAL behaves like CROSS JOIN.
Upvotes: 3