• ベストアンサー

外部結合

外部結合でどうしても理解できないパターンがあるので どなたか詳しい人がいたら教えてください。 ・まず、テーブルは下記のa_tblとb_tblの2テーブルです。  SQL> desc a_tbl;  名前 型  ------ ---------------  A1 CHAR(4)  A2 CHAR(4)  A3 CHAR(1)  SQL> desc b_tbl;  名前 型  ------ -----------  B1 CHAR(4)  B2 CHAR(4)  B3 CHAR(1) ・それぞれの内容は、  SQL> select * from a_tbl;  A1 A2 A3  ---- ---- -  1001 A001 1  1002 A002 0  1003 A003 1  1004 A004 0  1005 A005 1  SQL> select * from b_tbl;  B1 B2 B3  ---- ---- -  1001 B001 1  1002 B002 0  1003 B003 1  1004 B004 0 ・この2つのテーブルに対して、下記のselectを行います。  SQL> select * from a_tbl, b_tbl where b1(+)=a1 and b3(+)='1';  A1 A2 A3 B1 B2 B3  ---- ---- -- ---- ---- --  1001 A001 1 1001 B001 1  1002 A002 0  1003 A003 1 1003 B003 1  1004 A004 0  1005 A005 1 ・私の予想では、下記の様になると思ったのですが、結果は  上記の様になります。  どのような考え方をすれば上記の結果になるのか教えてください。  A1 A2 A3 B1 B2 B3  ---- ---- -- ---- ---- --  1001 A001 1 1001 B001 1  1003 A003 1 1003 B003 1

質問者が選んだベストアンサー

  • ベストアンサー
  • takasgy
  • ベストアンサー率42% (30/71)
回答No.4

通常の結合では、二つのテーブの等しい値をもつもののみ出力の対象となります。 でも、商品の受注データの一覧を表示する場合、出荷データがあればその情報も出力したい!ってな場合なんかはこれではこまります。 出荷データがばかりに受注データが表示されなければ意味がなくなるわけですから。 外部結合を使用すると主になるテーブルの値に対応する値が他のテーブルにない場合でも出力対象とすることができます。 この場合、存在しないレコードのカラムにはnullが設定されます。 b1(+)=a1の部分から考えますと、a1に対応するb1があればb1のデータを出力し、なければbテーブルのカラムにはnullが設定されます。 b3(+)='1'の部分についても、b3が'1'であればbテーブルのデータを出力するが、なければbテーブルのカラムにはnullが設定されます。 ということで、a1に対応するb1が存在する場合は以下ようになります。  A1 A2 A3 B1 B2 B3  ---- ---- - ---- ---- -  1001 A001 1 1001 B001 1  1002 A002 0 1002 B002 0  1003 A003 1 1003 B003 1  1004 A004 0 1004 B004 0  1005 A005 1 null null null さらに、b3が'1'でない場合、そのデータにはnullが割り当てられるので  A1 A2 A3 B1 B2 B3  ---- ---- - ---- ---- -  1001 A001 1 1001 B001 1  1002 A002 0 null null null  1003 A003 1 null null null  1004 A004 0 1004 B004 0  1005 A005 1 null null null bテーブルのカラムb3が'1'の場合だけbテーブルの値が出力されるという結果になると思うのですが。 といいながら、ちがったらごめんやなほんま...

CUNCUN
質問者

お礼

ありがとう御座います! なんとなく分かった気がします!

その他の回答 (3)

noname#1802
noname#1802
回答No.3

おろろ? すいません。下記の結果になるから上記の結果になるように したいのだと勘違いしました。 確かに「下記の結果になると思った」ってかいてあります。 すいません。早とちりでした。 ってことは何も私の回答のような方法は取る必要ありませんね^^; お恥ずかしい・・・・

CUNCUN
質問者

お礼

いえいえ、回答して頂いて大変感謝しております。 私が分かり辛い質問をしただけなので、気にせず これからも助けてください!

noname#1802
noname#1802
回答No.2

外部結合を使用する場所の問題であるとおもいます。 select * from a_tbl, b_tbl where A1 = B1 and B3 = "1" で、 1001 A001 1 1001 B001 1 1003 A003 1 1003 B003 1 の3行を抽出します。次に、 select a_tbl.*, null, null, null from a_tbl, b_tbl where A1 = B1(+) and B3 != "1" で 1002 A002 0 (null null null) 1004 A004 0 (null null null) 1005 A005 1 (null null null) を作成し、この2つを order by A1 で UNION 結合するというのはどうですか? select * from a_tbl, b_tbl where A1 = B1 and B3 = "1"    #1個目のSQL union select a_tbl.*, null, null, null from a_tbl, b_tbl where A1 = B1(+) and B3 != "1"    #2個目のSQL order by A1 ; こんな感じですかね? 私の使っているDBには union っていうのがあるんですが oracle(ですか?)にあるかどうか知りません。

CUNCUN
質問者

お礼

すいません、私の質問の仕方が悪かったです。 ほしかった回答は、「私の予想結果」になるSQL文ではなく select * from a_tbl,b_tbl where b1(+)=a1 and b3(+)='1'の 結果がどのような考えで下記の結果になるかと言う質問です。  A1 A2 A3 B1 B2 B3  ---- ---- -- ---- ---- --  1001 A001 1 1001 B001 1  1002 A002 0  1003 A003 1 1003 B003 1  1004 A004 0  1005 A005 1

  • pcg733
  • ベストアンサー率78% (11/14)
回答No.1

select * from a_tbl, b_tbl where b1=a1 and b3='1'; とやればOKですが、はずしてたらごめんなさい。 (+)を外すだけです。

CUNCUN
質問者

お礼

すいません、私の質問の仕方が悪かったです。 ほしかった回答は、「私の予想結果」になるSQL文ではなく select * from a_tbl,b_tbl where b1(+)=a1 and b3(+)='1'の 結果がどのような考えで下記の結果になるかと言う質問です。  A1 A2 A3 B1 B2 B3  ---- ---- -- ---- ---- --  1001 A001 1 1001 B001 1  1002 A002 0  1003 A003 1 1003 B003 1  1004 A004 0  1005 A005 1

関連するQ&A

  • ACCESSのSQLの書き方

    ACCESSでのSQL文の書き方を教えてください。 テーブルtbl_Aとテーブルtbl_Bがあり, tbl_Aで得られた数値とtbl_Bで得られた数値を加えたものを結果として表示します。 どう書けばよろしいのでしょうか。どうしてもエラーになってしまいます。 イメージとしてはこんな感じです。 select (select ~~ from tbl_A where ~~)+(select ~~ from tbl_B where ~~) (もしoracleならば,「from dual」というのを最後に付けるんですが。)

  • SQL サブクエリで抽出したカラムについて

    サブクエリで抽出したカラムを 本クエリでの結果と一緒に表示したいのですが どのように実現してよいかわからず困っております。 詳細としては、下記のようなことをしたいと考えております。 文中の1)と2)は文章下部にあるSQLを指しております ----------------------------------------------------------- 最初は、1)のように凄く単純なSQLでよかったのですが 仕様が変わり、TBL2で取得した新しいカラムも一緒に 本クエリでの結果として取得できれば、SQLを2回実行せずに済むなと考えたのですが、 2)のように色々と試行錯誤したのですが、実現できません。 (2)は単なる空想ですが…) そこで、わかる方にお伺いしたいのですが、 副問い合わせで取得した複数カラムの中の1つのカラム【2)でいうところのTBL2.X】 を 2)のように"select TBL1.A , TBL2.X"として、結果を得ることは可能でしょうか。 ただし、 TBL1のカラムAは、TBL2に存在しない TBL2のカラムXは、TBL1には存在しない カラムBは、TBL1、TBL2に存在する の条件となっております 環境はMysqlです テーブル結合の方法も考えたのですが、 TBL2で、日付でソートし、その上位100件だけを 持ってきたいと思ったので、副問い合わせで一気に抽出しようとこの方法を考えまし た お分かりになる方がいらっしゃいましたらよろしくお願いします 1)SQL ------------ select TBL1.A from TBL1 where TBL1.B in ( select TBL2.B from TBL2 where 条件 ) 2)想像SQL(こんな感じの事をしたい) -------------- select TBL1.A , TBL2.X from TBL1 where TBL1.B in ( select TBL2.B , TBL2.X from TBL2 where 条件 order by TBL2.日付 desc limit 100 )

    • ベストアンサー
    • MySQL
  • オラクルで外部結合

    オラクル8iを使用しています。 テーブルを外部結合する場合のパフォーマンスについてお聞きしたいのですが、 下の二つのSQL文でパフォーマンスは変わってくるのでしょうか? (外部結合記号(+)を=の前後につけた場合) SELECT 項目 FROM テーブル1 A, テーブル2 B WHERE A.項目1 = B.項目1(+); SELECT 項目 FROM テーブル1 A, テーブル2 B WHERE B.項目1(+) = A.項目1;

  • SQLの外部結合について教えて下さい

    いつもお世話になっています。 SQL構文の外部結合が分らなくて困っています。 どうか教えて下さい。 JSPからString Nam = (request.getParameter("param"));で値を受け取ってその値でT_Tableと一致するデータのSQLを実行します。 SELECT * FROM T_Table where ID='"+ Nam +"' order by 日付 desc この結果とT_TableAの「番号」というフィールドと一致する問い合わせのSQLが分りません。自分なりに考えて作りましたがHTMLの部分の表示だけでレコードが表示されないので間違っているのだと思います。 色々調べてみましたが該当のサンプルがなかったので困っています。 教えて下さい!宜しくお願い致します。 【自分で作成してみたSQLです】 テーブルはSQL Serverです。 "SELECT * FROM T_Table where ID='"+ Nam +"' INNER JOIN where ID='"+ Nam +"' ON [T_Table].[番号] = [T_TableA].[番号] order by 日付 desc"

    • ベストアンサー
    • Java
  • 外部結合と等価結合のパフォーマンスの違いについて(ビューの場合)

    Oracle10gでのSQL文の違いについて教えて下さい。 前回の質問は、ストアドプロシージャに記述 されていて、バッチとして動かしています。 と書きましたが、ビューの場合のパフォーマンスの違いは どうなるのでしょうか?ビューの場合も同じような現象です。 下記の2つのSQL文は外部結合ありと外部結合なしの違いだけで、 他は変わりありません。 外部結合ありのほうは 結果がすぐに返されるのですが、外部結合なしのほうは 結果が返ってこない、あるいはかなり時間がかかるという 現象が起きています。 SQL文は簡略して記述していますが、SELECT句には、 TO_CHAR()やSUM(CASE WHEN ...THEN ...ELSE...)が使用してあり 少し重くなる処理も含まれています。 この2つのSQL文でパフォーマンスに影響している原因は 何なんでしょうか?オプティマイザとか実行計画とかの 説明を読んだのですが、いまいちよく解りません。。 自分では中級者以下だと思っていますので、わかりやすく 説明して頂けたら助かります。宜しくお願い致します。 (外部結合ありのSQL) SELECT  a.項目1,  a.項目2,  a.項目3,  a.項目4,  a.項目5 FROM  TBL_A a,  TBL_B b WHERE  a.項目1 = b.項目1(+) AND  a.項目2 = b.項目2(+) AND  a.項目3 = b.項目3(+) AND  a.項目4 = b.項目4(+) AND GROUP BY  a.項目1,  a.項目2,  a.項目3,  a.項目4,  a.項目5 (外部結合なしのSQL) SELECT  a.項目1,  a.項目2,  a.項目3,  a.項目4,  a.項目5 FROM  TBL_A a,  TBL_B b WHERE  a.項目1 = b.項目1 AND  a.項目2 = b.項目2 AND  a.項目3 = b.項目3 AND  a.項目4 = b.項目4 AND GROUP BY  a.項目1,  a.項目2,  a.項目3,  a.項目4,  a.項目5

  • 巨大テーブルの外部結合

    巨大なテーブル同士を結合する際に、みなさんはどのように結合されますか?もっともパフォーマンスのある方法を模索しているところです。 テーブルA:約900万件 テーブルB:約400万件 テーブルAのインデックスはカラム:idです。 テーブルBにはインデックスはありません。 取得したいのはBテーブルに含まれるAテーブルのidの件数です。 select  count(id) from B where A.id = B.id なんてやると、数時間かかります。 select count(id) from B where exists(select * from A where A.id = B.id) ですと、約3hぐらいかかりました。 inで実行すると等価結合したときと変わらないぐらいになります。 こういう場合、皆さんはどう結合されていますか? お知恵を拝借できると幸いです。 ちなみにoracle 8iです。 よろしくお願いいたします。

  • NOT EXITSを用いたデータ抽出

    以下の様のテーブル内容でb_tblにないa_tblのデータを抽出するにはNOT EXITSを使用したSQLはどの様に記述すればよいでしょうか。尚、NOT INでは以下の様な記載になりますが、これを単純にNOT EXITSに置き換えると同様の結果が得られません。 select distinct a from a_tbl where a not in (select a from b_tbl); a_tblの内容 項目a 10001 10001 11001 12002 13003 13003 13003 14004 14004 15005 15005 16006 16006 16006 17007 18008 18008 18008 b_tblの内容 項目a 10001 11001 13003 15005 17007 結果 12002 14004 16006 18008

  • 3テーブル外部結合方法について

    3つのテーブルを外部結合したいのですが・・・、 こんがらがってしまいました。 A,B,Cの3テーブルがあり、A,B,Cの順に外部結合 (LEFT OUTER JOIN)したいのですが、 A,BのテーブルについてはWhere句の条件指定が 必要です。 Select From (Select AA.a From A AA Where b = xxxx) BB Left Outer Join (Select CC.b From B CC Where c = eeee and BB.a = CC.b) On ???? こんな感じでつまづいてしまいました・・・

  • 【至急】SQLの結合について教えてください。

    select * from A where ab = '1' and cd = '2' select ef from B where ab = '1' and cd = '2' and ef = '3' 至急質問させてください。 上記SQLを結合したいです。(Oracleです) 取得したいデータはAのテーブルの全項目で、 取得条件として、Bのテーブルの項目ef = '3' だったらという条件を加えたいです。 キー項目は両テーブルとも同じ(ab, cd)です。 どのようなSQLがスマートでしょうか。。 無知で申し訳ございませんが、ご教授いただけますと幸いです。 よろしくお願いいたします。

  • FROM テーブル 名前 ?

    SQLについての質問です. select a.name, b.id from テーブルA a テーブルB b where... というSQLのfromのあとはどういう意味なのでしょうか? テーブルAと同じ型のaを作る という意味なのでしょうか??