1

特定のクエリのwhere句を使用して外部結合を行う方法を理解するのに問題があります。JOINキーワードを使用して結合を実行できます。私が実行しようとしているクエリは次
のとおりです。--booksテーブル内のすべての本のリストを表示します。書籍が顧客によって注文された場合は、対応する注文番号と顧客の出身地も記載してください

これがテーブルの構造です

    desc customers
Name      Null     Type         
--------- -------- ------------ 
CUSTOMER# NOT NULL NUMBER(4)    
LASTNAME  NOT NULL VARCHAR2(10) 
FIRSTNAME NOT NULL VARCHAR2(10) 
ADDRESS            VARCHAR2(20) 
CITY               VARCHAR2(12) 
STATE              VARCHAR2(2)  
ZIP                VARCHAR2(5)  
REFERRED           NUMBER(4)    
REGION             CHAR(2)      
EMAIL              VARCHAR2(30) 

desc orders
Name       Null     Type         
---------- -------- ------------ 
ORDER#     NOT NULL NUMBER(4)    
CUSTOMER#           NUMBER(4)    
ORDERDATE  NOT NULL DATE         
SHIPDATE            DATE         
SHIPSTREET          VARCHAR2(18) 
SHIPCITY            VARCHAR2(15) 
SHIPSTATE           VARCHAR2(2)  
SHIPZIP             VARCHAR2(5)  
SHIPCOST            NUMBER(4,2)  

desc orderitems
Name     Null     Type         
-------- -------- ------------ 
ORDER#   NOT NULL NUMBER(4)    
ITEM#    NOT NULL NUMBER(2)    
ISBN              VARCHAR2(10) 
QUANTITY NOT NULL NUMBER(3)    
PAIDEACH NOT NULL NUMBER(5,2)  

desc books
Name     Null     Type         
-------- -------- ------------ 
ISBN     NOT NULL VARCHAR2(10) 
TITLE             VARCHAR2(30) 
PUBDATE           DATE         
PUBID             NUMBER(2)    
COST              NUMBER(5,2)  
RETAIL            NUMBER(5,2)  
DISCOUNT          NUMBER(4,2)  
CATEGORY          VARCHAR2(12) 

joinを使用すると、次のようにして正しい結果であると私が信じているものを表示することができます。

SELECT b.title, c.state, order#
FROM customers c JOIN orders o USING (customer#)
JOIN orderitems oi USING (order#)
RIGHT OUTER JOIN books b USING (isbn);


TITLE                          STATE     ORDER#
------------------------------ ----- ----------
HOW TO GET FASTER PIZZA                         
THE WOK WAY TO COOK                             
REVENGE OF MICKEY              MI          1012 
REVENGE OF MICKEY              GA          1019 
REVENGE OF MICKEY              WA          1009 
REVENGE OF MICKEY              TX          1014 
BODYBUILD IN 10 MINUTES A DAY  FL          1003 
HANDCRANKED COMPUTERS          MI          1012 
SHORTEST POEMS                 GA          1005 
PAINLESS CHILD-REARING         GA          1001 
PAINLESS CHILD-REARING         NJ          1004 
PAINLESS CHILD-REARING         FL          1016 
PAINLESS CHILD-REARING         MI          1012 
PAINLESS CHILD-REARING         GA          1011 
COOKING WITH MUSHROOMS         WY          1020 
COOKING WITH MUSHROOMS         ID          1008 
COOKING WITH MUSHROOMS         FL          1003 
COOKING WITH MUSHROOMS         WA          1000 
COOKING WITH MUSHROOMS         WA          1009 
COOKING WITH MUSHROOMS         FL          1018 
COOKING WITH MUSHROOMS         NJ          1015 
HOLY GRAIL OF ORACLE           TX          1007 
BUILDING A CAR WITH TOOTHPICKS                  
BIG BEAR AND LITTLE DOVE       FL          1017 
BIG BEAR AND LITTLE DOVE       TX          1007 
BIG BEAR AND LITTLE DOVE       MI          1012 
DATABASE IMPLEMENTATION        IL          1002 
DATABASE IMPLEMENTATION        TX          1007 
DATABASE IMPLEMENTATION        FL          1003 
DATABASE IMPLEMENTATION        WY          1013 
DATABASE IMPLEMENTATION        FL          1018 
DATABASE IMPLEMENTATION        NJ          1010 
HOW TO MANAGE THE MANAGER      GA          1001 
E-BUSINESS THE EASY WAY        TX          1007 
E-BUSINESS THE EASY WAY        FL          1006 

 35 rows selected 

これは、where句の結合に対して私が試したものです。

-- using where clause
SELECT b.title,  c.state, oi.order#
FROM customers c, orders o, orderitems oi, books b
WHERE c.customer# = o.customer#
AND o.order# = oi.order#
AND oi.isbn(+) = b.isbn;

しかし、このクエリを実行すると、次のようになります

TITLE                          STATE     ORDER#
------------------------------ ----- ----------
BODYBUILD IN 10 MINUTES A DAY  FL          1003 
REVENGE OF MICKEY              GA          1019 
REVENGE OF MICKEY              TX          1014 
REVENGE OF MICKEY              MI          1012 
REVENGE OF MICKEY              WA          1009 
DATABASE IMPLEMENTATION        FL          1018 
DATABASE IMPLEMENTATION        WY          1013 
DATABASE IMPLEMENTATION        NJ          1010 
DATABASE IMPLEMENTATION        TX          1007 
DATABASE IMPLEMENTATION        FL          1003 
DATABASE IMPLEMENTATION        IL          1002 
COOKING WITH MUSHROOMS         WY          1020 
COOKING WITH MUSHROOMS         FL          1018 
COOKING WITH MUSHROOMS         NJ          1015 
COOKING WITH MUSHROOMS         WA          1009 
COOKING WITH MUSHROOMS         ID          1008 
COOKING WITH MUSHROOMS         FL          1003 
COOKING WITH MUSHROOMS         WA          1000 
HOLY GRAIL OF ORACLE           TX          1007 
HANDCRANKED COMPUTERS          MI          1012 
E-BUSINESS THE EASY WAY        TX          1007 
E-BUSINESS THE EASY WAY        FL          1006 
PAINLESS CHILD-REARING         FL          1016 
PAINLESS CHILD-REARING         MI          1012 
PAINLESS CHILD-REARING         GA          1011 
PAINLESS CHILD-REARING         NJ          1004 
PAINLESS CHILD-REARING         GA          1001 
BIG BEAR AND LITTLE DOVE       FL          1017 
BIG BEAR AND LITTLE DOVE       MI          1012 
BIG BEAR AND LITTLE DOVE       TX          1007 
HOW TO MANAGE THE MANAGER      GA          1001 
SHORTEST POEMS                 GA          1005 

 32 rows selected

必要に応じて構造を構築するSQLへのリンクは次のとおりですhttps://www.dropbox.com/s/7tpbpz1hbufj3qn/JLDB_Build_8.sql

where句の結合で何が間違っている/違うのかを理解するのに苦労しています。任意の助けや指示をいただければ幸いです。ありがとう。

4

3 に答える 3

1

さらに掘り下げた結果、これを見つけました

これはhttp://docs.oracle.com/cd/B19306_01/server.102/b14200/queries006.htmからのものです

A と B が複数の結合条件で結合されている場合は、これらすべての条件で (+) 演算子を使用する必要があります。そうしないと、Oracle Databaseは単純な結合の結果の行のみを返しますが、外部結合の結果がないことを通知する警告またはエラーは表示されません。

外部クエリで 1 つのテーブルを指定し、内部クエリで別のテーブルを指定した場合、(+) 演算子は外部結合を生成しません。

私はそれを次のように動作させることができました:

SELECT b.title, c.state, o.order# FROM customers c, orders o, orderitems oi, books b WHERE c.customer#(+) = o.customer# AND o.order#(+) = oi.order# AND oi.isbn(+) = b.isbn;

于 2013-03-15T01:09:55.267 に答える
1

これを試して:

SELECT b.title,  o.state, o.order#
FROM books b
, (select o.order#, oi.isbn, o.customer#, c.state
   from orders o, orderitems oi, customers c
   where o.order# = oi.order#
   and   c.customer# = o.customer#
) o
WHERE 
AND o.isbn(+) = b.isbn;
于 2013-03-14T21:17:42.793 に答える
1

結合を使用する場合は、明示的な左/右結合を行うことをお勧めします。例えば..

Select A.*, B.*, C.*
from TableA A 
 left outer join TableB B
 on A.field1 = B.fkfield1
 and A.field2 0 B.fkfield2
 ...

 left outer join TableC C
 on A.field1 = C.fkfield1
 and A.field2 0 C.fkfield2
 ...

この場合、テーブル A のレコードはテーブル B のレコードと一致します。テーブル B に一致がない場合、テーブル B の列は null になります。2 番目の結合は最初の結合と同様に機能します。この場合も、テーブル C の fkfield1 に (テーブル A の) field1 からの一致する値がない場合、null が表示されます。

一方、最初のテーブルではなく 2 番目のテーブルのすべてのレコードを照合する必要がある場合は、「内部結合」を実行する必要があります。上記の例の「左外部結合」を「内部結合」に置き換えるだけです。

ありがとう!

@レオ

于 2013-03-14T21:17:53.087 に答える