• ベストアンサー

テーブルを結合するとき

MySQLのSQL文です。 TblAのID、Nmがあり、TblBにID、Adrsがあるとします。 次の2つのSQL文の結果は同じになります。 そもそもこの2つの書き方には何か違う意味があるのでしょうか。 CREATE View TblC1 as SELECT TblA.ID, TblA.Nm, TblB.Adrs FROM TblA INNER JOIN TblB ON TblA.ID = TblB.ID; CREATE View TblC2 as SELECT TblA.ID, TblA.Nm, TblB.Adrs FROM TblA ,TblB where TblA.ID = TblB.ID; また、TblAにはありTblBには含まれないレコードを出すときは CREATE View TblC3 as SELECT TblA.ID, TblA.Nm, TblB.Adrs FROM TblA LEFT JOIN TblB ON TblA.ID = TblB.ID; 逆にTblBにありTblAには含まれないレコードを出すときは CREATE View TblC4 as SELECT TblA.ID, TblA.Nm, TblB.Adrs FROM TblA RIGHT JOIN TblB ON TblA.ID = TblB.ID; としています。 これをwhereを使った書き方ではできないのでしょうか。

  • MySQL
  • 回答数2
  • ありがとう数3

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

  • ベストアンサー
  • takubou05
  • ベストアンサー率52% (11/21)
回答No.1

まず、 InnerJoinか where句で 結合指定をするかですが、 基本的にはどちらでもかまいません。 実行計画を見ても違いはないです。 実行計画はselect句の前に”explain”を追加すると確認できます。 参考URL : http://dev.mysql.com/doc/refman/5.1/ja/explain.html >また、TblAにはありTblBには含まれないレコードを出すときは これは、差集合といいます。 mysql での差集合の抽出方法は、 where句に、"not exitst"で出来ます。 頑張ってみてください。

Hirorin_20
質問者

お礼

ありがとうございました

その他の回答 (1)

回答No.2

MySQLのビュー表は、MySQL 5.0と実装が遅く、「FROM句でのサブクエリ(インラインビュー)」を使えないなどいろいろ制限があるので、初歩のSQLの勉強に使うにはお薦めしません。 内部結合だけの話なら、ONでの結合条件と、WHEREで結合条件を指定するのに差異はありません。 しかし、外部結合の場合は、まったく意味が違ってきます。 ON句で指定するのは結合条件で、どのように表を結合するかを指定します。この結合条件に合致しなかったものは、左側の表、右側の表などを基準にnullで返されます。 一方、WHERE句で書くのは制限条件であり、最終的な結果に影響します。 差分検索する基本的な方法として、 (1)left joinして、結合キーがnullとなるもの (2)サブクエリの「not exists」 (3)サブクエリの「not in」 を使うといった方法があります。 このうち、not inは、性能を出しにくい構文です。 MySQLでは、サブクエリの実装がMySQL 4.1と遅かったこともあり、サブクエリでなくジョインに書き換える方が性能を出しやすいといったケースがたくさんあります。 以下、ぱっと思いついた構文で、実機確認していませんが、参考まで。 -- t1にあり、t2にない行 -- left join select t1.c1 from t1 left join t2 on t1.c1=t2.c1 where t2.c1 is null -- not exists select c1 from t1 where c1 not exists(select 1 from t2 where t1.c1=t2.c1) -- not in select c1 from t1 where c1 not in(select c1 from t2)

Hirorin_20
質問者

お礼

ありがとうございました。

関連するQ&A

  • 3つのテーブルを結合させたSQL文について

    3つのテーブルを結合させたSQL文について作成方法を教えてください。 よろしくお願いいたします。 【テーブル構成】 テーブル名---項目名/項目名・・・です。 tblA---id/del_flg/name tblB---id/del_flg/add tblC---id/del_flg/family 各テーブルはidによりリンクされます。 tblAのdel_flgは在籍者=0 退職者=1で、一人1レコードです。 tblBでは住所管理をしています。 旧情報を残したいので、更新時には新たにdel_flg=0でレコードを作成し、既存レコードはdel_flg=1に更新します。 tblCは、既婚者のみ作成されるレコードです。 つまり、tblBとtblCは、レコードが存在しない、あるいはdel_flg=0のみ、del_flg=0とdel_flg=1が混在 のどれかのパターンになります。 【やりたいこと】 いま、これらすべてのテーブルを全部つなげて、在籍している人の情報だけ集めたいのです。 tblAからはdel_flg=0のレコードをすべて取得したうえで、tblBとtblCにdel_flg=0のレコードがあればその情報も取得したい。 【経過】 select * from (tblA inner join tblB on tblA.id = tblB.id ) inner join tblC on tblA.id = tblC.id とりあえずwhere条件をつけなくても、tblCに存在している人しか取得ができないのです。 where条件も含めて、上記条件のもと、希望するようなSQLの組み立て方をご教授ねがいたいのでよろしくお願いいたします。 できれば、早目の回答が希望です。

    • ベストアンサー
    • MySQL
  • テーブルの結合について

    以下の二つを実行すると、2 の方がかなり速いのですが理由が分かりません。 分かる方教えてもらっていいですか? DBはMYSQLでInoDBです。 ちなみに Aは1万件、B は10万件ほど 1 のSQL SELECT * FROM A LEFT JOIN (SELECT * FROM B WHERE ・・・ GROUP BY XXX) B ON A.id = B.XXX WHERE ・・・ GROUP BY A.id 2 のSQL (SELECT * FROM A ・・・ GROUP BY ID ) A LEFT JOIN (SELECT * FROM B WHERE ・・・ GROUP BY XXX) ON A.ID = B.XXX.ID

  • マテビューのNOTNULL設定について

    いつもお世話になっています マテリアライズドビューを作成しました。 抽出等は正しく動作しているのですが、Key(TBLMV_TENCD,TBLMV_KAICD)に設定した項目以外は NOTNULLが”YES”になってしまっています。 以下の処理をどのように変更すればよいか、教えて頂けないでしょうか? よろしくお願いします。 (ORACLE10を使用しています) (TBLA、TBLB、TBLC共に全項目NOTNULL="NO"になっております) ※ALTERで行うような気がするのですが、もしそうだとしてもどのように変更すればいいのか検討がつきません(新規にALTER文を追加するなら出来そうですが、まとめることが出来ないかと思い質問させて頂きました) CREATE MATERIALIZED VIEW TBLMV BUILD IMMEDIATE USING NO INDEX REFRESH FORCE ON DEMAND AS SELECT TBLA_TENCD AS TBLMV_TENCD , TBLA_KAICD AS TBLMV_KAICD , TBLA_KINGAKU AS TBLMV_KINGAKU, ※NOT Null="YES"→"NO"にしたい TBLA_DATE AS TBLMV_DATE ※NOT Null="YES"→"NO"にしたい FROM TBLA LEFT JOIN TBLC ON TBLA_KAICD = TBLC_KAICD WHERE ・・・・・ UNION ALL SELECT TBLB_TENCD , TBLB_KAICD , TBLB_KINGAKU, TBLB_DATE FROM TBLB LEFT JOIN TBLC ON TBLB_KAICD = TBLC_KAICD WHERE ・・・・・ ; ALTER TABLE TBLMV ADD CONSTRAINT TBLMV_P01 PRIMARY KEY ( TBLMV_TENCD, TBLMV_KAICD ) USING INDEX STORAGE ( INITIAL 1M NEXT 1M MINEXTENTS 1 MAXEXTENTS 10) ;

  • サブクエリ

    見ていただいてありがとうございます。 ただいま、業務でSQLを作成しているのですが、 なにぶん経験が浅く、行き詰ってしまっています。 どなたかわかる方、どうぞご教授ください。 環境は、 OS:WinXP Honme PG:VB.net Server:SQLServer2000 です。 わからないのは、以下の様なSQLです。 SELECT * from (SELECT tblA.field1 , tblA.field2, MAX(tblA.field3) AS MxNum FROM ( (tblA INNER JOIN tblB ON tblA.field1 = tblB.field1) INNER JOIN tblC ON tblA.field2 = tblC.field1 ) INNER JOIN tblD ON tblA.field4 = tblD.field1 GROUP BY tblA.field1,tblA.field2,tblA.field3) サブクエリの使い方がおかしいらしく エラーとなってしまいます。 (「fromの後に不要な文字が・・・」という  構文エラーになります。) サブクエリとして使用しようとしている()内の SELECT文は、クエリアナライザで実行すると 正常に終了して結果が返ってきます。 大変困っているので、 どうか宜しくお願いいたします。

  • ビューについて、教えてください

    いつもお世話になっております。 ビューについて、教えて下さい。 以下のビュー「ABVW」を作成しましたが、TBLAやTBLBの内容が変更された場合、 ビュー上のデータは自動で置き換わるのでしょうか? CREATE VIEW ABVW  SELECT * FROM TBLA UNION ALL SELECT * FROM TBLB 以上、よろしくお願いします。 ※いろいろなサイトではマテビューはリフレッシュ機能のようなものがあると書かれており、  マテビューを作成しようとしたのですが、TBLA/TBLBは”キーなし”が原因なのかは  わからないのですが、うまく作成できず、普通のビューで行うことにしました。

  • Recordset参照の記述方法

    WindowXP、ACCESS2003、を使っています SQLを使ってRecordsetを使う場合 (要点だけをCodingします) テーブル;TblAのフィールド:id, aa, ab、があるとして Set RS=OpenRecordset("SELECT * From TblA") とした時、RS!aaでフィールドaaを参照できます Debug.Print "RS=" & RS!aa さてテーブルを2つ使った場合 どう参照するかわからないでいます 例えば Set RS=OpenRecordset("SELECT TblA.id, TblB.bb From TblA INNER JOIN TblB ON TblA.id = TblB.id;") 但し テーブル;TblAのフィールド:id, aa, ab、 テーブル;TblBのフィールド:id, ba, bb、 を想定しています この時 bb、を参照するのに Debug.Print "RS=" RS!FileB.bb ではおかしいし Debug.Print "RS=" RS!bb ではTblA,TblB、のどちらのフィールドかわかりません (今はbb、はTblBにしかないのでわかりますが) 質問点はこれをどう記述するのか知りたいのですが よろしくお願いします

  • テーブル結合について

    SQL Serverで、メイン、サブ1、サブ2、サブ3、サブ4というテーブルがあり、以下のSQLを実行すると、メインにあるすべてのデータ(10列)が抽出されます。 SELECT * FROM メイン INNER JOIN サブ1 ON メイン.name1=サブ1.id INNER JOIN サブ2 ON メイン.name2=サブ2.id INNER JOIN サブ3 ON メイン.name3=サブ3.id しかし、上記のSQL文に追加して、 SELECT * FROM メイン INNER JOIN サブ1 ON メイン.name1=サブ1.id INNER JOIN サブ2 ON メイン.name2=サブ2.id INNER JOIN サブ3 ON メイン.name3=サブ3.id INNER JOIN サブ4 ON メイン.name4=サブ4.id とすると、メイン内の10列のうち、2列しか抽出されません。 サブ4を結合しても、一つ目のSQL文と同じ結果を抽出したかったのですが、どこがおかしいのでしょうか? SQL文がまずいのか、サブ4のテーブル内容のせいなのか、SQL Serverの設定がおかしいのか、さっぱり見当がつきません。 足りない情報がありましたら補足いたしますので、どうぞよろしくお願いします。

  • WHERE句はJOIN結合前結合後どちらに効くのか

    以下の2つのSQLを比較してどちらがパフォーマンスが良いでしょうか。 先に抽出して結合した方が良いと昔聞いた事がありましたが 記憶があいまいになってしまいました。 (1) SELECT * FROM A JOIN B ON A.*** = B.*** WHERE A.*** = '0001' (2) SELECT * FROM (SELECT * FROM A WHERE A.*** = '0001') AS A JOIN B ON A.*** = B.***

  • Accessの内部結合

    こんにちは。 Accessでcateテーブルとgoodsテーブルがあります。 select * from goods inner join cate on goods.cateid = cate.id; クエリデザインで、テーブルとテーブルを結合して上記のようなSQLができました。 これは動作することを確認しました。 SQLビューで下記のようなSQLを書きました。 select * from goods inner join cate on left(goods.cateid,5) = cate.id; しかしながら、動きませんでした。 VBAを使わずに、Accessの標準のクエリデザインから上記のようなSQLを実行させることは可能でしょうか? クエリデザインでselect left(cateid,5) as cateid from goodsというTESTクエリをつくり、TESTクエリとcateテーブルとジョインさせれば解決しそうなことはわかるのですが・・・ 宜しくお願いします。

  • 複数の副問合わせにて、一つだけデータがない場合の対処法は?

    テーブルの各区分に応じて、数量を個々に集計するSQLを作成しております。 そして以下のようなSQLを作りました。 SELECT TBLA.SURYO_1 ,TBLB.SURYO_2 , TBLC.SURYO_3 ,TBLD.SURYO_4 FROM (SELECT SUM(SURYO) AS SURYO_1 FROM TEST_TABLE WHERE TEST_KUBUN = '1' GROUP BY SURYO) TBLA, (SELECT SUM(SURYO) AS SURYO_2 FROM TEST_TABLE WHERE TEST_KUBUN = '2' GROUP BY SURYO) TBLB, (SELECT SUM(SURYO) AS SURYO_3 FROM TEST_TABLE WHERE TEST_KUBUN = '3' GROUP BY SURYO) TBLC, (SELECT SUM(SURYO) AS SURYO_4 FROM TEST_TABLE WHERE TEST_KUBUN = '4' GROUP BY SURYO) TBLD しかし、この方法ですと、区分'1','2','4'はデータがあるのに対して、区分'3'は データがないことにより、SQLを実行すると、対象データがないという結果となります。 当然個別にSQLを実行すればよいですが、速度的に4回もSQLを実行するのは効率悪いので、 出来れば一回で行いたいのですけど、区分'3'がデータがなくても、他の3つの区分のデータ を取得する方法はありますでしょうか? よろしくお願いします。