質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

解決済

1回答

3760閲覧

[Rails4.2]抽出条件を絞った2つのテーブルのLeft Outer Joinの方法

MakitoKezuka

総合スコア18

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

1クリップ

投稿2016/04/07 02:42

Rails初心者です。
RailというよりSQLの問題の気がしないでもないのですが、ある、リレーションが結ばれている2つのテーブルのLeft Outer Joinの方法について教えて下さい。
まずはシンプルにこんな感じのテーブルです。


<テーブル1:Item>
has_many :item_color_price

[カラム]
-id
-name

テーブル2:Item_Color_price
belongs to :item

[カラム]
-id
-color
-item_id
-price


で、この時に、例えば全アイテムの黄色(color)の値段が知りたい、ということで、下記の様な表を作りたいです。

item_id item_name price
1 AAA ¥200
2 BBB ¥150
3 CCC ¥ 50
4 DDD (null)
5 EEE (null)

ポイントは、Item_Color_priceテーブルのcolorで絞った条件で、ItemテーブルとLeft Joinしたいです。
(黄色を持っていないアイテムも一覧には表示したい)

ruby

1@items = Item.includes(:item_color_prices).where("item_color_prices.color = Yelloow").references(:item_color_prices)

というような書き方をしても、SQLとしては、whereが最後にきてしまうため、結果としては、INNER JOINとなってしまいます。
どんなメソッド、あるいはSQLでも構わないので、書き方のアドバイスをお願いできませんでしょうか。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

SQLで抽出するのであれば、
item_color_prices から黄色の行を取得した後で外部結合をするとよいです。
副問い合わせを利用します。

RailsのActiveRecordを用いた解決法を検討してみたのですが、
私ではよい案が見つかりませんでした、すみません。。

(Arel::Table や Arel::SelectManager など、ActiveRecord内部のクラスを利用するらしいです)

副問い合わせを用いたSQL

SQL

1SELECT 2 items.id AS item_id, 3 items.name AS item_name, 4 price 5FROM 6 items 7LEFT JOIN ( 8 SELECT 9 item_id, 10 price 11 FROM 12 item_color_prices 13 WHERE 14 color = "yellow" 15 ) yellow_prices 16ON items.id = yellow_prices.item_id;

SQLite上での動作確認結果

items および item_color_prices の内容を確認したのち、
副問い合わせを用いたSQLの実行結果を確認しています。

SQL

1sqlite> SELECT id, name FROM items; 21|AAA 32|BBB 43|CCC 54|DDD 65|EEE 7 8sqlite> SELECT id, color, price FROM item_color_prices; 91|yellow|200 102|yellow|150 113|yellow|50 124|red| 135|blue| 14 15sqlite> SELECT 16 ...> items.id AS item_id, 17 ...> items.name AS item_name, 18 ...> price 19 ...> FROM 20 ...> items 21 ...> LEFT JOIN ( 22 ...> SELECT 23 ...> item_id, 24 ...> price 25 ...> FROM 26 ...> item_color_prices 27 ...> WHERE 28 ...> color = "yellow" 29 ...> ) yellow_prices 30 ...> ON items.id = yellow_prices.item_id; 311|AAA|200 322|BBB|150 333|CCC|50 344|DDD| 355|EEE|

投稿2016/04/07 06:07

sutonea

総合スコア207

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

MakitoKezuka

2016/04/07 07:55

ありがとうございます!なるほど、副問い合わせ(サブクエリ)と言うんですね。 Arel:については、調べてみましたが、どうやらleft joinは相当面倒らしいので、直接SQLを記述することとします。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問