• ベストアンサー

3つ以上のテーブルを結合して絞り込むには?

MySQL勉強中のものです。 初歩的な質問ですいませんが、 以下のような3つのテーブルがあります。 テーブルA(店名) A店 B店 C店 D店 テーブルB(販売品目) パソコン ビデオ 冷蔵庫 液晶テレビ デジカメ テーブルC(支払い方法) クレジットカード 銀行振り込み 代引き このデータから、テレビとビデオを販売していて かつクレジットカードに対応しているお店を検索したいと思うのですが、 どうもうまくいきません。 この場合、どのようにSQL文を組み立てればよいのでしょうか。 LEFT JOINで1つに結合すると、カラムごとにレコードが重複して GROUP BYでうまく絞り込めません。 そもそもテーブルの作り方を間違えているのでしょうか。 考え方のヒントだけでも結構ですのでよろしくお願いいたします。

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

  • ベストアンサー
  • nda23
  • ベストアンサー率54% (777/1415)
回答No.4

>品目、支払いそれぞれを「AND」にして なるほど、IN(1,2) は確かに「OR」です。方法は幾つかあります。 【その1】 HAVING COUNT(B.*)=2 を追加する。 【その2】 SELECT A.店名 FROM ((店舗テーブル A INNER JOIN (SELECT 店舗ID FROM 販売品目テーブル WHERE 品目コード=1) B ON A.店舗ID=B.店舗ID) INNER JOIN (SELECT 店舗ID FROM 販売品目テーブル WHERE 品目コード=2) C ON A.店舗ID=C.店舗ID) INNER JOIN (SELECT 店舗ID FROM 支払い方法テーブル WHERE 支払い方法コード=1) D ON A.店舗ID=D.店舗ID GROUP BY A.店名 個人的には後者が好みかな。特に件数が多い場合は先に条件で絞り 込んだクエリから更に抽出するので、全体を処理してから抽出する HAVING条件より高速のはずです。 Oracleなんかでは絶対に後者ですね。ただ、MySQLはバージョンにより サブクエリが弱いと言う意見もあります。バージョン毎に検証した 経験が無いので、これについては何とも言えません。

misoshio
質問者

お礼

たびたびのご回答ありがとうございます。 【その2】のほうは完璧にできました。 サブクエリの組み方が理解できておらず、 本やネットで調べてもわからず悩み続けていましたが やっとこれで先に進めます。 しかし、GROUP BY + HAVINGのやり方は 私の勉強不足のため解決できませんでした。 No.3の回答者様のところにも書きましたが、 ANDの絞り込み項目が品目と支払いのように複数になると 思うような結果が得られませんでした。

その他の回答 (4)

  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.5

ん~?これってサブクエリいらないのでは? SELECT DISTINCT A.* FROM テーブルA AS A INNER JOIN テーブルB AS B1 ON A.店舗ID=B1.店舗ID AND B1.品目コード=1 INNER JOIN テーブルB AS B2 ON A.店舗ID=B2.店舗ID AND B2.品目コード=2 INNER JOIN テーブルC AS C ON C.店舗ID=C.店舗ID AND C.支払い方法コード = 1

misoshio
質問者

お礼

ご回答ありがとうございます。 完璧にできました。 こういうやり方もあるんですね。 データが増えた場合に No.4の回答者様のやり方とどちらが高速なのでしょうか。

回答No.3

WHERE句でのIN条件 と GROUP BY + HAVING を組み合わせれば、できると思いますけど。 WHERE 列名2 IN('値1','値2') GROUP BY 列1 HAVING COUNT([DISTINCT] 列名2)=2 商演算といった方法もあるでしょうけどね。

misoshio
質問者

お礼

ご回答ありがとうございます。 品目と支払いのどちらか一方だけが複数であれば ご教授くださったGROUP BY + HAVINGでできました。 しかし、私の知識と経験が乏しいため、 それぞれが複数になったときに絞り込むやり方がわかりませんでした。 もう少し調べてみようと思います。 商演算はちょっと調べてみましたがなかなか難しそうですね。 でも今後のためにじっくり勉強してみます。

  • nda23
  • ベストアンサー率54% (777/1415)
回答No.2

品目コードは1=テレビ、2=ビデオ、支払い方法コードは1=クレジットと 仮定すると、この条件に一致するものが対象になります。 【SQLの一例】 SELECT A.店名 FROM (店舗テーブル A INNER JOIN 販売品目テーブル B ON A.店舗ID=B.店舗ID) INNER JOIN 支払い方法テーブル C ON A.店舗ID=C.店舗ID WHERE B.品目コード IN (1,2) AND C.支払い方法コード=1 GROUP BY A.店名

misoshio
質問者

補足

nda23様 ご回答いただき誠にありがとうございます。 ご提示いただいた例の通りに実行すると、 品目部分が「OR」になりませんでしょうか。 品目コードを(1,2,3)のように追加すると結果が増えてしまいます。 品目、支払いそれぞれを「AND」にして絞り込みたいのですが、 その場合はどうすればよいのでしょうか。 お忙しいところ申し訳ございませんが、 何卒ご教授お願いいたします。

  • nda23
  • ベストアンサー率54% (777/1415)
回答No.1

掲題のテーブルは各個別情報のマスタのようです。 これだけでは結合条件がありませんので、JOINできません。 別に、店舗コード+販売品目コード、店舗コード+支払い方法コードの ようなテーブルがあるはずです。それを提示してください。

misoshio
質問者

補足

情報が少なくてすいませんでした。 以下のようなテーブルになります。 店舗テーブル(テーブルA) 店舗ID 店名 ……etc 1    A 2    B 3    C 4    D 販売品目テーブル(テーブルB) 店舗ID 品目コード ……etc(商品名等は別テーブル) 1    1 1    2 1    3 2    2 2    3 3    1 4    4 支払い方法テーブル(テーブルC) 店舗ID 支払い方法コード ……etc(詳細は別テーブル) 1    1 2    1 3    1 3    2 3    3 これ以外にも、「メーカー」テーブルや 「カテゴリー」テーブルなどもあります。 これらを1つに結合すると 販売品目と支払いテーブルのレコードがそれぞれ増えて 正しい結果になってくれないのです。 お手数をおかけしますが、よろしくお願いします。

関連するQ&A