2

クエリ ビルダーを使用してテーブル間の内部結合を作成するのに苦労しています。次の関係を持つ 3 つのテーブルがあります。

航空機クラス 1:m 航空機タイプ m:1 ブランド

航空機のクラスを指定して、ブランドのリストを取得できるクエリを作成しようとしています。次の SQL クエリは正しく機能します。

SELECT * FROM brands
INNER JOIN aircraft_types ON brands.id = aircraft_types.brand_id
INNER JOIN aircraft_classes ON aircraft_types.aircraft_class_id = aircraft_classes.id
WHERE aircraftClassID = $class

私は現在持っています:

$brands = DB::table('brands')
->join('aircraft_types', 'brands.id', '=', 'aircraft_types.brand_id')
->join('aircraft_classes', 'aircraft_types.aircraft_class_id', '=', 'aircraft_classes.id')
->where('aircraft_classes.id', '=', $class)
->get(array('brands.id', 'brands.brand_name'));

ただし、これは同じブランドの複数のインスタンスを返します。ブランドが一度だけ返されるように、テーブル間の内部結合を作成するのに苦労しています。

どこが間違っていますか?

4

1 に答える 1

5

基本SQLクエリが正しくないため、問題はLaravelとは何の関係もありません。同じブランドの航空機タイプが複数ある場合、クエリはブランド情報を複数回取得します (JOIN によって通知されます)。

  1. まず、aircraft_classesフィルタリングしているので参加する必要はありませんaircraft_classes_id
  2. 第二に、あなたが使用しなければならないブランドの明確なリストを取得するには、DISTINCTまたはGROUP BY

SQLクエリは次のようになります

SELECT id, brand_name 
  FROM brands 
 WHERE id IN
(
  SELECT DISTINCT brand_id
    FROM aircraft_types
   WHERE aircraft_class_id = 1
);

また

SELECT b.id, b.brand_name
  FROM aircraft_types t JOIN brands b
    ON t.brand_id = b.id
 WHERE aircraft_class_id = 1
 GROUP BY b.id, b.brand_name;

これがSQLFiddleのデモです

Laravel Query Builder コードは次のようになります。

$brands = DB::table('aircraft_types AS t')
            ->join('brands AS b', 't.brand_id', '=', 'b.id')
            ->where('t.aircraft_class_id', '=', 1)
            ->groupBy('b.id', 'b.brand_name')
            ->select('b.id', 'b.brand_name')
            ->get();

サンプル出力var_dump($brands);

array(2) {
  [0]=>
  object(stdClass)#133 (2) {
    ["id"]=>
    int(1)
    ["brand_name"]=>
    string(6) "Brand1"
  }
  [1]=>
  object(stdClass)#134 (2) {
    ["id"]=>
    int(2)
    ["brand_name"]=>
    string(6) "Brand2"
  }
}
于 2013-07-23T05:15:21.780 に答える