3

私はpostgresqlを使用していますが、これはsqlfiddle.comでも確認しました。

私のテーブルと要素は次のとおりです。

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);

Book and Publisher に参加して、Oxford University Press から出版されている本を手に入れたいと思っています。

これは機能します:

select b.name
from Book as b, Publisher as p
where b.pid = p.pid and p.name ='Oxford University Press';

これはしません:

select b.name
from Book as b natural join Publisher as p
where p.name = 'Oxford University Press';

これでもしません:

select *
from Book natural join Publisher;

どうして??

4

2 に答える 2

3

と の両方のテーブルに同じ名前の列のペアが複数ありidますname。そう

select *
from book 
natural join publisher;

と同等です

select *
from book b
join publisher p on b.pid = p.pid 
and b.name = p.name;

ドキュメントごと:

NATURAL は USING の省略形です。両方の入力テーブルに表示されるすべての列名で構成される USING リストを形成します。USING と同様に、これらの列は出力テーブルに 1 回だけ表示されます。共通の列名がない場合、NATURAL は CROSS JOIN のように動作します。

于 2016-11-06T16:21:58.087 に答える
3

使用しないでくださいnatural join。発生するのを待っているバグです。代わりに、明示的なonorusing句を使用します。

select b.name
from Book b join
     Publisher p
     using (pid)
where p.name = 'Oxford University Press';

また:

select b.name
from Book b join
     Publisher p
     where b.pid = p.pid
where p.name = 'Oxford University Press';

問題natural joinは 2 つあります。まず、宣言された外部キー関係ではなく、共通に基づいて列を比較します。両方のテーブルにname列とid列があるため、少なくとも、自然結合クエリは次と同等です。

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';

(同じ名前の列が他にもあるかもしれません。) 「Oxford University Press」という名前の本はないと思うので、一致するデータはありません。

2番目の問題は関連しています。結合に使用される列を明示的に含めないことにより、クエリのリーダーはわかりません。これにより、クエリのデバッグと理解が難しくなります。私の場合、私が作成するほとんどすべてのテーブルにはCreatedAtCreatedBy列があるためnatural join、データベースでは s が機能しません。

于 2016-11-06T16:20:31.057 に答える