ORACLE外部接続
10182 ワード
今日の開発過程で面倒な外部接続の問題に遭遇し、最後まで良い解決方法が見つからず、最後にunion allで実現するしかなく、性能は外部接続に及ばないが、少なくとも外部接続の限界を広げた.
まず、私のテスト用の3つのテーブルとデータを提供します(左右の外部接続の道理は同じで、私は左接続だけをまとめました):
一、一つの接続条件を使用する外部接続:
この2つの文のクエリの結果が同じであることは容易にわかります.そのため、この2つの文法は変換できると言えますが、最初の書き方が理解しやすいのは明らかです.これもoracleの公式提案です.公式文書は、Oracle recommends that you use the FROM clause OUTER JOIN syntax rather than the Oracle join operatorと述べています.
KC 21中のakb 020はKC 24中と等しいものが110と1000であり、KC 24中には2つのakb 020が110の記録があるため、結果として3つの接続上のものが生成され、残りの2つに一致していないものが表示され、KC 24の項目に対応してNULLで充填されることも左外接続が実現される目的である.
二、二つの接続条件を使用する場合:
この2つの文のクエリの結果も同じであり、この2つの文は等価であることがわかります.AKB 020とakc 190が同時に等しい場合にのみ一致するという意味です.同じように明らかに最初の文が理解しやすい.2番目の文を直接与える場合、最終的にどのような結果になるか想像しにくいことがあります.ここではOracle政府がなぜこのように書くのか理由を示しています.If A and B are joined by multiple join conditions,then you must use the(+)operator in all of these conditions.
3、3つのテーブルのうち、2つのテーブルには外部接続関係があり、もう1つのテーブルには外部接続関係がありません.oracleでは、SQL文の1つのテーブルに2つのテーブルを外部接続できません.
4、2つの接続テーブルのうち、接続条件は2つあり、1つは外部接続、1つは内部接続です.そうすると、どのような結果になりますか.
五、全外接続oracleは全接続に対して接続条件の左右に「(+)」をつけることをサポートしていない.from句にfull outer joinを使用し、on句に接続条件を加える方法は一つしかない.
六、終わり!
まず、私のテスト用の3つのテーブルとデータを提供します(左右の外部接続の道理は同じで、私は左接続だけをまとめました):
KC21 :
create table KC21
(
AKB020 VARCHAR2(14) not null,
AKC190 VARCHAR2(18) not null,
AAC001 VARCHAR2(20) not null
);
INSERT INTO KC21 (AKB020, AKC190, AAC001) VALUES('110', '266', '1302012062942');
INSERT INTO KC21 (AKB020, AKC190, AAC001) VALUES('456', '369', '1302012063210');
INSERT INTO KC21 (AKB020, AKC190, AAC001) VALUES('1000', '472', '1302012045811');
INSERT INTO KC21 (AKB020, AKC190, AAC001) VALUES('123', '335', '1302012063275');
KC24 :
create table KC24
(
AKB020 VARCHAR2(14) not null,
AKC190 VARCHAR2(18) not null,
AAE072 VARCHAR2(20) not null
);
insert into KC24 (AKB020, AKC190, AAE072)values ('110', '335', '2188038055');
insert into KC24 (AKB020, AKC190, AAE072)values ('11', '369', '2188038092');
insert into KC24 (AKB020, AKC190, AAE072)values ('1000', '472', '2188038197');
insert into KC24 (AKB020, AKC190, AAE072)values ('110', '339', '2188038058');
KB01 :
create table KB01
(
AKB020 VARCHAR2(14) not null,
AKB021 VARCHAR2(50)
);
insert into KB01 (AKB020, AKB021)values ('1000', ' ');
insert into KB01 (AKB020, AKB021)values ('110', ' A');
insert into KB01 (AKB020, AKB021)values ('123', ' B');
insert into KB01 (AKB020, AKB021)values ('456', ' C');
insert into KB01 (AKB020, AKB021)values ('11', ' D');
oracle公式では、from句でleft outer join/right outer join/full outer joinを使用し、もう1つはwhere句でよく知られている記号「(+)」を使用する2つの方法の理解を書きたいと考えています.一、一つの接続条件を使用する外部接続:
SQL> select * from kc21 left outer join kc24 on kc21.akb020=kc24.akb020;
AKB020 AKC190 AAC001 AKB020 AKC190 AAE072
-------------- ------------------ -------------------- -------------- ------------------ --------------------
110 266 1302012062942 110 335 2188038055
1000 472 1302012045811 1000 472 2188038197
110 266 1302012062942 110 339 2188038058
123 335 1302012063275
456 369 1302012063210
SQL> select * from kc21 ,kc24 where kc21.akb020=kc24.akb020(+);
AKB020 AKC190 AAC001 AKB020 AKC190 AAE072
-------------- ------------------ -------------------- -------------- ------------------ --------------------
110 266 1302012062942 110 335 2188038055
1000 472 1302012045811 1000 472 2188038197
110 266 1302012062942 110 339 2188038058
123 335 1302012063275
456 369 1302012063210
この2つの文のクエリの結果が同じであることは容易にわかります.そのため、この2つの文法は変換できると言えますが、最初の書き方が理解しやすいのは明らかです.これもoracleの公式提案です.公式文書は、Oracle recommends that you use the FROM clause OUTER JOIN syntax rather than the Oracle join operatorと述べています.
KC 21中のakb 020はKC 24中と等しいものが110と1000であり、KC 24中には2つのakb 020が110の記録があるため、結果として3つの接続上のものが生成され、残りの2つに一致していないものが表示され、KC 24の項目に対応してNULLで充填されることも左外接続が実現される目的である.
二、二つの接続条件を使用する場合:
SQL> select * from kc21 left outer join kc24 on (KC21.akb020=kc24.akb020 and KC21.akc190=KC24.akc190);
AKB020 AKC190 AAC001 AKB020 AKC190 AAE072
-------------- ------------------ -------------------- -------------- ------------------ --------------------
1000 472 1302012045811 1000 472 2188038197
110 266 1302012062942
123 335 1302012063275
456 369 1302012063210
SQL> select * from kc21,kc24 where kc21.akb020=kc24.akb020(+) and kc21.akc190=KC24.akc190(+);
AKB020 AKC190 AAC001 AKB020 AKC190 AAE072
-------------- ------------------ -------------------- -------------- ------------------ --------------------
1000 472 1302012045811 1000 472 2188038197
110 266 1302012062942
456 369 1302012063210
123 335 1302012063275
この2つの文のクエリの結果も同じであり、この2つの文は等価であることがわかります.AKB 020とakc 190が同時に等しい場合にのみ一致するという意味です.同じように明らかに最初の文が理解しやすい.2番目の文を直接与える場合、最終的にどのような結果になるか想像しにくいことがあります.ここではOracle政府がなぜこのように書くのか理由を示しています.If A and B are joined by multiple join conditions,then you must use the(+)operator in all of these conditions.
3、3つのテーブルのうち、2つのテーブルには外部接続関係があり、もう1つのテーブルには外部接続関係がありません.oracleでは、SQL文の1つのテーブルに2つのテーブルを外部接続できません.
SQL> SELECT A.akb020, A.AKC190, B.akb020, B.akc190, C.akb021
2 FROM kc21 A, kc24 B, kb01 C
3 WHERE A.akb020 = B.akb020(+)
4 AND A.akc190 = B.akc190(+)
5 AND A.akb020 = C.akb020;
AKB020 AKC190 AKB020 AKC190 AKB021
-------------- ------------------ -------------- ------------------ --------------------------------------------------
1000 472 1000 472
110 266 A
123 335 B
456 369 C
これは、第2のステップに基づいて第3のテーブルに関連して病院のコードを病院名に変換したようなものであることがわかり、このような結果が得られたのは理解できる.4、2つの接続テーブルのうち、接続条件は2つあり、1つは外部接続、1つは内部接続です.そうすると、どのような結果になりますか.
SQL> select * from kc21,kc24 where kc21.akb020=kc24.akb020(+);
AKB020 AKC190 AAC001 AKB020 AKC190 AAE072
-------------- ------------------ -------------------- -------------- ------------------ --------------------
110 266 1302012062942 110 335 2188038055
1000 472 1302012045811 1000 472 2188038197
110 266 1302012062942 110 339 2188038058
123 335 1302012063275
456 369 1302012063210
SQL> select * from kc21,kc24 where kc21.akc190=kc24.akc190;
AKB020 AKC190 AAC001 AKB020 AKC190 AAE072
-------------- ------------------ -------------------- -------------- ------------------ --------------------
123 335 1302012063275 110 335 2188038055
456 369 1302012063210 11 369 2188038092
1000 472 1302012045811 1000 472 2188038197
SQL> select * from kc21,kc24 where kc21.akb020=kc24.akb020(+) and kc21.akc190=kc24.akc190;
AKB020 AKC190 AAC001 AKB020 AKC190 AAE072
-------------- ------------------ -------------------- -------------- ------------------ --------------------
1000 472 1302012045811 1000 472 2188038197
SQL> select * from kc21,kc24 where kc21.akb020=kc24.akb020 and kc21.akc190=kc24.akc190;
AKB020 AKC190 AAC001 AKB020 AKC190 AAE072
-------------- ------------------ -------------------- -------------- ------------------ --------------------
1000 472 1302012045811 1000 472 2188038197
上のいくつかのSQL文は1つと2つ目を使って、私たちは自然に3つ目を得ることができて、これも常識に合っていて、3つ目の結果セットはちょうど1つ目と2つ目の交差です.3番目と4番目のSQL文の効果は同じです.複数の接続条件を持つ2つのテーブルが接続時に「(+)」と書かれていない場合、oracleは単純な等値内で接続されているとみなされます.これもoracleの公式声明です.If Aand B are joined by multiple join conditions,then you must use the(+)operator in all of these conditions.If you do not, then Oracle Database will return only the rows resulting from a simple join, but without a warning or error to advise you that you do not have the results of an outer join. 五、全外接続oracleは全接続に対して接続条件の左右に「(+)」をつけることをサポートしていない.from句にfull outer joinを使用し、on句に接続条件を加える方法は一つしかない.
SQL> select * from kc21 full outer join kc24 on (kc21.akb020=KC24.akb020);
AKB020 AKC190 AAC001 AKB020 AKC190 AAE072
-------------- ------------------ -------------------- -------------- ------------------ --------------------
110 266 1302012062942 110 335 2188038055
1000 472 1302012045811 1000 472 2188038197
110 266 1302012062942 110 339 2188038058
123 335 1302012063275
456 369 1302012063210
11 369 2188038092
6 rows selected
この結果はよく理解され、一致条件を満たすものは成功記録として返され、他のテーブルに対応するフィールドを満たさないものはNULLで満たされる.六、終わり!