2

次のように、5 つのテーブルがあるとします。

CREATE TABLE T1 (
FIRST_NAME VARCHAR2(100),
LAST_NAME VARCHAR2(100),
CITY NUMERIC,
SALARY NUMERIC);

CREATE TABLE T2 (
CITY NUMERIC,
DISTRICT  NUMERIC);

CREATE TABLE T3 (
DISTRICT NUMERIC,
DOMAIN NUMERIC);

CREATE TABLE T4 (
DOMAIN NUMERIC,
DETAILS_BOOK NUMERIC);

CREATE TABLE T5 (
DETAILS_BOOK NUMERIC,
FIRST_NAME VARCHAR2(100),
LAST_NAME VARCHAR2(100),
EMAIL VARCHAR2(100));

INSERT INTO T1 VALUES ('john', 'doe',1001,1000); 
INSERT INTO T1 VALUES ('jack', 'jill',1001,2000);
INSERT INTO T1 VALUES ('jeff', 'bush',1001,1500);

INSERT INTO T2 VALUES (1001,1);

INSERT INTO T3 VALUES (1,543);

INSERT INTO T4 VALUES (543,22);

INSERT INTO T5 VALUES (22,'john', 'doe','john@22.com');
INSERT INTO T5 VALUES (44,'john', 'doe','john@44.com');
INSERT INTO T5 VALUES (22,'jeff', 'bush','jeff@22.com');
INSERT INTO T5 VALUES (44,'jeff', 'bush','jeff@44.com');

ここで、テーブル t2、t3、および t4 に対応する給与と電子メールを含む t1 のすべてのレコードが必要です。結果は次のようになります。

FIRST_NAME | LAST_NAME | SALARY | EMAIL
--------------------------------------------------
john       | doe       |  1000  | john@22.com
jeff       | bush      |  1500  | jeff@22.com
jack       | jill      |  2000  | (NULL)

私がこれまでに得たものは次のとおりです。

SELECT T1.FIRST_NAME, T1.LAST_NAME,T1.SALARY,T5.EMAIL
FROM T1,T2,T3,T4,T5
WHERE   T1.FIRST_NAME = T5.FIRST_NAME (+)
and     T1.LAST_NAME = T5.LAST_NAME(+)
AND     T1.CITY = T2.CITY
AND     T2.DISTRICT = T3.DISTRICT
AND     T3.DOMAIN = T4.DOMAIN
AND     T4.DETAILS_BOOK = T5.DETAILS_BOOK

最初の 2 行のみを返します。

4

1 に答える 1

10

代わりにこれを試してください:

SELECT 
  T1.FIRST_NAME, 
  T1.LAST_NAME,
  T1.SALARY,
  T5.EMAIL
FROM T1
LEFT JOIN T2  ON T1.CITY         = T2.CITY
LEFT JOIN T3  ON T2.DISTRICT     = T3.DISTRICT
LEFT JOIN T4  ON T3.DOMAIN       = T4.DOMAIN
LEFT JOIN T5  ON T4.DETAILS_BOOK = T5.DETAILS_BOOK
             AND T1.FIRST_NAME   = T5.FIRST_NAME
             AND T1.LAST_NAME    = T5.LAST_NAME;

SQL フィドルのデモ

これにより、次のことが得られます。

| FIRST_NAME | LAST_NAME | SALARY |       EMAIL |
-------------------------------------------------
|       john |       doe |   1000 | john@22.com |
|       jeff |      bush |   1500 | jeff@22.com |
|       jack |      jill |   2000 |      (null) |

問題は、あなたの結合が のように機能したINNER JOIN後、内部結合が外部結合からの一致しない行を排除することです。OUTER JOININNER

注意:クエリで訴えLEFT OUTER JOINた古い暗黙OUTERの結合構文の代わりに、ANSI SQL-92 の明示的な構文を使用しました。INNER

LEFT OUTER JOIN古い外部結合構文の代わりに を使用してみてください。after s は避けINNER JOINてくださいOUTER JOIN

詳細については、次を参照してください。


アップデート:

FROMそれらの間に を含む句に多くのテーブル参照がある場合、各テーブルは句1JOINから懇願する次のテーブルと結合され、結果として一時的な結果セットが生成され、次にこの一時的な結果セットが次のテーブルと結合されます。の場合、 左または右があります。FROMOUTER JOIN

  • LEFT JOIN左側のテーブルの一致しない行が含まれます。ここで、
  • RIGHT JOIN右側のテーブルの一致しない行が含まれます。

JOIN選択するデータによっては、演算子の両側にあるテーブルとその順序に注意する必要があります。


1:これは単に論理的なクエリ処理順序ですが、実際の順序は常にクエリ オプティマイザ次第です。

于 2013-01-13T09:16:55.757 に答える