関連テーブルの検索方法

このQ&Aのポイント
  • 1本のSQLでrecipe_idだけの一覧を取得する方法とクエリーの呼び方について教えてください。
  • ロジックは「ズッキーニ、トマト」で検索すると「ズッキーニとオリーブのトマトパスタ」と「ズッキーニとオリーブのトマトのマリネ」が取得できます。
  • 名前でのLike検索はせず、より効率的な方法があれば教えてください。
回答を見る
  • ベストアンサー

関連テーブルの検索方法

以下のテーブル関連で、以下のロジックで、recipe_id だけの一覧を取得するのは、1本のSQLではどのようにすればよいでしょうか? #あとこのような、クエリーの事をなんと呼べばいいのでしょうか…。 #適切質問タイトルが思い浮かばなかったので、提示してもらえるとありがたいです。 recipe recipe_id | name 1 | ズッキーニとオリーブのトマトパスタ 2 | ズッキーニとオリーブのトマトのマリネ 3 | ズッキーニのアリオリ 4 | 野菜のフリッター recipe_ingredients recipe_ingredient_id | recipe_id | master_id 1 | 1 | 1 | ※ ズッキーニとオリーブのトマトパスタ 2 | 1 | 2 | ※ ズッキーニとオリーブのトマトパスタ 3 | 1 | 3 | ※ ズッキーニとオリーブのトマトパスタ 4 | 1 | 4 | ※ ズッキーニとオリーブのトマトパスタ 5 | 2 | 1 | ※ ズッキーニとオリーブのトマトのマリネ 6 | 2 | 2 | ※ ズッキーニとオリーブのトマトのマリネ 7 | 2 | 3 | ※ ズッキーニとオリーブのトマトのマリネ 8 | 3 | 1 | ※ ズッキーニのアリオリ 9 | 3 | 4 | ※ ズッキーニのアリオリ 10 | 4 | 1 | ※ 野菜のフリッター ※ はわかりやすくつけただけで、実際のテーブルデータではないです。 vegetables vegetable_id | name 1 | ずっきーに 2 | おりーぶ 3 | とまと 4 | にんにく ロジックはアンド検索で: 検索条件「ズッキーニ、トマト」で検索したら、  「ズッキーニとオリーブのトマトパスタ」と「ズッキーニとオリーブのトマトのマリネ」 検索条件「にんにく、ズッキーニ」で検索したら、  「ズッキーニとオリーブのトマトパスタ」と「ズッキーニのアリオリ」 が見つかる。 名前でLike検索はしない。 全く持って想像がつかないので教えてください。 ちょっと考えてみたんですが、↓では、1~4のレシピ全てが見つかってしまうのですよね…。 select recipe_id from recipe inner join recipe_ingredients using ( recipe_id ) inner join vegetables using ( vegetable_id ) where vegetables.name like '%ずっきーに%' or vegetables.name like '%にんにく%' ; もしかして、以下でしょうか? select recipe_id from recipe inner join recipe_ingredients using ( recipe_id ) inner join vegetables using ( vegetable_id ) where vegetables.name like '%にんにく%' INTERSECT select recipe_id from recipe inner join recipe_ingredients using ( recipe_id ) inner join vegetables using ( vegetable_id ) where vegetables.name like '%ずっきーに%'; なんとなくコストが高そうなので、他に方法はないでしょうか?

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

  • ベストアンサー
回答No.1

recipe_ingredients表のmaster_id列と、vegetables表のvegetable_id列が対応しているのですね? recipe表の野菜の名前はカタカナですが、vegetables表のname列はひらがななのですか? などなど、いろいろと引っ掛かる点があるのですけどね。 SQL例を示しますから、実行結果が期待通りか確認すると共に、どういうことをやっているか調べてみてください。 select tR.* from tR inner join (select R_id from tRI inner join tV on M_id=V_id where name in('ズッキーニ','トマト') group by R_id having count(*)=2) as x on tR.R_id=x.R_id order by tR.R_id

superplastic
質問者

お礼

ありがとうございます! having って一度も使ったことありませんでした…。 group by した結果に対して、条件で絞り込むことができるんですね! 二つのVegetablesの名前で検索したら、 2行のrecipe_ingredientsが引っかかったものが全てに 合致したもので、あるから、recipe_id を Group by でカウントを取った 結果に対して、絞り込むと言うことですよね? ご指摘いただいたとおり、 [recipe_ingredients.master_id と vegetables.vegetable_id が対応]で正しいです。 すみませんサンプル作るときにカラム名を間違えてしまったようです。 vegetablesについても、 ずっきーに、おりーぶ、とまと はカタカナのつもりになっていました。 ご指摘の通りです。すみません。 情けない不備がたくさんあったのに、 回答いただいてありがとうございました! 助かりました。

関連するQ&A

  • テーブル結合について

    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の設定がおかしいのか、さっぱり見当がつきません。 足りない情報がありましたら補足いたしますので、どうぞよろしくお願いします。

  • テーブルを結合

    テーブルの結合に関して質問します。 ネットなどでinner joinを使った複数のテーブル結合が参考として 書いてあったのですが(3つまで), 4つテーブルを結合する事は 出来るのでしょうか? A,B,CテーブルにはID,NAMEがあります。 DテーブルにはA,B,CテーブルのIDがあります。 参考サイトを見て3つのテーブルを結合するSQLが以下になります。 SELECT a.name, b.name, c.name FROM a INNER JOIN (b INNER JOIN c ON b.id = c.id) ON a.id = c.id よろしければアドバイスお願いします。

  • データーベースの結合について

    はじめまして。 先日異動で新しい職場につき、マイクロソフトアクセスを使用し始めたド初心者です。 早速ですが教えてください。 使用しているアクセスは2000です。 http://okweb.jp/kotaeru.php3?q=246849 ↑にて参考にさせていただきましたが、 SELECT * FROM メイン INNER JOIN サブ1 ON メイン.name1=サブ1.id INNER JOIN サブ2 ON メイン.name2=サブ2.id INNER JOIN サブ3 ON メイン.name3=サブ3.id のようにテーブルを4つ結合したいのです。 現在、2つのテーブルを結合することはできましたが、 3つ以上のテーブルの結合ができずに困っています。 上記のようにやってみると 「構文エラー:演算子がありません」と表示されます。 .ASPという拡張子のものですがそれがいけないのでしょうか? (正式には SQL = "SELECT * FROM メイン INNER JOIN サブ1 ON メイン.name1=サブ1.id" と、1行で書かないと認識しません SQL = "SELECT * FROM メイン INNER JOIN サブ1 ON メイン.name1=サブ1.id INNER JOIN サブ2 ON メイン.name2=サブ2.id INNER JOIN サブ3 ON メイン.name3=サブ3.id" とするとエラーになります。 ) 以前、勤めていた方の仕事を引き継いだのですが聞ける人もいないので途方にくれています。 質問自体がおかしいかもしれませんがどうぞ初心者にも理解できる回答をよろしくお願いします。

  • トマトの冷たいパスタのレシピは?

    トマトを使った冷たいパスタを食べたくて 昨年いろいろなサイトをみて作ったら美味しかったので 今年も作ってみようと思ったのですが どのサイトかわからず・・・ 適当に作ってみたらマズイ! 何かが違ったようなんです。 確か使った材料は ・トマト ・にんにく ・パセリ ・オリーブオイル ・塩 コショウは?使ったような? バジルを使ったパスタもあるようですか 昨年作った時はバジルは使わなかったと思います。 そこでこれたの材料だけで美味しいパスタのレシピをご存知でしたら教えて下さい。 にんにくはみじん切り?すりおろし? ここも忘れてしまたのでどちらが良いのでしょうか? またパスタ以外の材料は1度冷蔵庫で冷やした気がしますが 冷やして食べる時にパスタと合わせるのでしょか? それともパスタと合わせてから冷やした方が良いのでしょうか? オリーブオイルの分量は? レシピは4人分くらいでお願いいたします。

  • 3つのテーブルを結合した場合のWHERE

    MySQLで3つのテーブルを結合した場合のWHEREがよくわかりません。 まず、下のような2つのテーブルがあるとします。 【テーブルaa】 ID | Name -------------- 1 | x 2 | y 3 | z 【テーブルbb】 ID | hizuke | category --------------------- 1 | stamp1 | a 1 | stamp2 | b 1 | stamp3 | c 2 | stamp1 | a 2 | stamp2 | d 3 | stamp1 | c この2つのテーブルを結合して、同じIDでhizukeが最大値のデータを抽出するクエリは、 http://okwave.jp/qa/q6918385.htmlを参考にして、 SELECT aa.Name, bb.category FROM bb INNER JOIN aa ON aa.ID = bb.ID where (bb.ID, bb.hizuke) in (SELECT bb.ID, max(bb.hizuke) FROM bb group by bb.ID ) ; でできました。 しかし、もう1つテーブルを結合すると期待した結果が得られなくなってしまいました。 【テーブルcc】 category | choice --------------------- a | ss b | tt c | uu というテーブルがあって、上のクエリで得られた bb.categoryと cc.categoryをリンクして、choiceを取得しようとしたのですがうまくいきません。 SELECT aa.Name, bb.hizuke, bb.category, cc.choice FROM bb INNER JOIN cc ON bb. category = cc. category INNER JOIN aa ON aa.ID = bb.ID where (bb.ID, bb.category, bb.hizuke) in (SELECT bb.ID, bb.category, max(bb.hizuke) FROM bb group by bb.ID ); というクエリでは、ダメなようです。 INNER JOINを入れ子にしたり、いろいろと試したのですがどうにもうまくいきません。 どうも私の力では解決困難なようです。どなたかヘルプを。

  • パスタが美味しくできません。

    パスタ大好きなんですが、家で作ると美味しくできません。何か足りない感じ。味がうすいというか、ホールトマトそのまんまの味というか・・・。本などでレシピ見ながら作るんですけど、お店のような味にはなりません。 大鍋がないのでたっぷりの湯でパスタを茹でていないのが原因?それとも塩加減が悪い? オリーブオイルはよくスーパーで売ってるものじゃダメ? トマト系は特にダメです。 なぜでしょう?

  • トマトのパスタ 味が足りない。

    トマトのパスタを作って食べました。味として塩コショウはきいていますが トマト以外のコクみたいな味が足りないんです。トマトのパスタで検索したら 昆布茶や味の素が必要みたいですが我が家にはありません。それ以外に何を 加えたら味がでてよくなるか、コクが出るかなど教えてください。 つくったときのレシピ アルデンテにしたパスタ 1人分 タカの爪 適量(ひとつまみくらい?) 塩コショウ 適量 オリーブオイル 適量 トマト1センチの角切りしたもの 半分 にんにく 適量 (チューブで5ミリ弱くらい) トマトベースのパスタで、冷静ではなく温かいパスタです。ドロドロのトマトソースの パスタではありません。よろしくお願いします。

  • スープパスタのレシピ

    東海地方にある「マリノ」というお店のスープパスタがとってもおいしいのです。 トマトスープなのですが、スープと言っても軽い感じではなく結構ボリュームがあります。具は鶏肉、玉ねぎ、ズッキーニ、ナス、パプリカが入ってました。鶏肉はどうも揚げてあるような感じです。 家で作ってみても、どうもコクというか深みがでません。 ぴったりそのままのレシピではなくてもよいのですが、こんな風につくるとおいしいよ、というレシピ、アドバイスあれば教えてください! よろしくお願いします。

  • サブクエリ内で INNER JOIN は

    グルーピング内で、あるカラムの最大値のレコードで絞り込む方法は、 以下のサイトで知ることができましたが。 http://www.yokablo.com/20120905717.html tb_score +-------+-------+-------+ | c_name | game | c_score | +-------+-------+-------+ | 山田 | 高飛び | 90 | +-------+-------+-------+ | 山田 | 徒競走 | 85 | +-------+-------+-------+ | 山田 | 玉入れ | 90 | +-------+-------+-------+ | 鈴木 | 徒競走 | 85 | +-------+-------+-------+ | 鈴木 | 騎馬戦 | 50 | +-------+-------+-------+ | 室伏 | 綱引き | 100 | +-------+-------+-------+ | 室伏 | 玉入れ | 10 | +-------+-------+-------+ SQL文: SELECT * FROM tb_score INNER JOIN ( SELECT c_name, MAX(c_score) AS MAXSCORE FROM tb_score GROUP BY c_name ) AS TBDUMMY1 USING (c_name) WHERE c_score = MAXSCORE 私の場合、t_score の親テーブル名`t_company`と、 子テーブル`t_items`がありまして、 以下のようなことをやりたかったのですが、エラーとなります。 上記SQL をサブクエリにします。 select * from ( SELECT * FROM tb_score INNER JOIN ( SELECT c_name, MAX( c_score ) AS MAXSCORE FROM tb_score GROUP BY c_name ) AS TBDUMMY1 USING ( c_name ) INNER JOIN t_company ON t_company.c_name = tb_score.c_name WHERE c_score = MAXSCORE ) as T1 , t_items where T1.id_score = t_items.id_score 結果エラーメッセージは、 #1060 - Duplicate column name 'c_name' でした。 エラー箇所が、 GROUP BY c_name か、 USING ( c_name ) か、 INNER JOIN t_company ON t_company.c_name = tb_score.c_name なのか、分かりません。 SQL の規則としてやってはいけないことをやっていると想像してますが、 ご指摘・ご指導いただけると大変に助かります。 よろしくお願いします。

    • ベストアンサー
    • MySQL
  • 紐付いている3つのテーブルに対しての検索条件の指定がうまくいきません・・。

    紐付いている3つのテーブルに対しての検索条件の指定がうまく書けません。 3つのテーブルが紐付いています。 ・main_tableのIDと、note_id_tableのID ・note_id_tableのnote_IDと、note_value_tableのnote_ID main_table ID, name ----------- 1, aaa 2, bbb 3, ccc 4, ddd 5, eee note_id_table ID, note_ID ----------- 1, 1 1, 2 1, 3 1, 4 3, 5 3, 6 4, 7 4, 8 4, 9 5, 10 note_value_table note_ID, note_value ----------- 1, AAAA1 2, BBBB1 3, CCCC1 4, DDDD1 5, AAAA3 6, EEEE3 7, FFFF4 8, GGGG4 9, HHHH4 10, IIII5 検索の対象にしたいのは、note_valueです。 今まで、「note_valueに検索文字列が含まれている」main_tableのレコードを取得していました。 SELECT main_table.* FROM main_table LEFT JOIN note_id_table ON main_table.id = note_id_table.id LEFT JOIN note_value_table ON note_id_table.note_ID = note_value_table.note_ID WHERE note_value_table.note_value LIKE '%AAA%' 上記クエリだと、note_valueにAAAを含んでいるnote_ID:1,5を持つ、 main_tableのID:1,3のレコード、2件が返ってきます。 これを、検索文字列のNOT検索とAND検索に対応させたいのです。 NOT検索について、 WHERE NOT(note_value_table LIKE '%AAA%') としてみたのですが、main_tableのID:1,3,4,5のレコードが返ってきました。 期待した動作は、main_tableのID:2,4,5でした。 まず、note_value_tableにデータを持っていないmain_table.id:2はNULLのようで、 この条件では無視されてしまうようです。 また、main_table.id:1,3が返ってきてしまうのは、 main_table.id:1に紐付いているnote_IDの内、2,3,4と main_table.id:3に紐付いているnote_IDの内、6に条件が引っかかってしまうようなのです。 AND検索ですが、上記クエリの条件を WHERE note_value_table LIKE '%AAA%' AND note_value_table LIKE '%BBB%' としたところ、0件となってしまいました。 期待した動作は、note_valueにAAAとBBBを含んでいるnote_ID:1を持つ、 main_tableのID:1のレコード、この1件が返ってくることでした。 どうもこの条件だと、一つのnote_valueにAAAとBBBが含まれていないとHITしないようです。 結局JOINしているので、note_valueの数だけ同じmain_tableが前にくっついてるイメージなんですよね。 main_tableのレコード末端に、紐付いているnote_valueのフィールドを横に繋げるか、 紐付いているnote_valueの文字列を連結したものを一つのフィールドとして解釈するようなことができれば 実現できるのかなぁと思いました。 試行錯誤の末に、パフォーマンスが非常に悪いんですが、下記クエリで機能的には実現できたのですが、 これでは使えないので何かいいアイディアなどあればご教授お願いしたいです。 サブクエリを使いたくないというのがあります。 --AAAの検索 JOINする時に検索してしまうようにしてみました。 また、そのためには、note_id_tableからnote_IDを取得できていないとだめなので、 サブクエリ化してみました。 SELECT main_table.* FROM main_table LEFT JOIN note_value_table ON note_value_table.note_ID IN (SELECT note_ID FROM note_id_table WHERE main_table.id = note_id_table.id) AND note_value_table LIKE '%AAA%' WHERE note_value_table.note_value IS NOT NULL --AAAのNOT検索 WHERE条件を逆にするだけにしました。 --AAAとBBBの検索 検索条件1つに対して、JOINを増やしていくようにしました。 JOINが増えるのもそうですが、サブクエリも倍になってしまい、 検索条件を増やせば増やすほどパフォーマンスが落ちてしまいます。。 SELECT main_table.* FROM main_table LEFT JOIN note_value_table AS note_value_table1 ON note_value_table1.note_ID IN (SELECT note_ID FROM note_id_table WHERE main_table.id = note_id_table.id) AND note_value_table1 LIKE '%AAA%' LEFT JOIN note_value_table AS note_value_table2 ON note_value_table2.note_ID IN (SELECT note_ID FROM note_id_table WHERE main_table.id = note_id_table.id) AND note_value_table2 LIKE '%AAA%' WHERE note_value_table1.note_value IS NOT NULL AND note_value_table2.note_value IS NOT NULL

    • ベストアンサー
    • MySQL