在Eloquent ORM和Laravel中加入的问题

Ben*_*son 2 php join laravel eloquent

我正在努力使用查询构建器来创建表之间的内部联接.我有三个表有以下关系:

aircraft_classes 1:m aircraft_types 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
Run Code Online (Sandbox Code Playgroud)

我目前有:

$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'));
Run Code Online (Sandbox Code Playgroud)

但是,这将返回同一品牌的多个实例.我正在努力在表之间创建一个内部联接,这样一个品牌只返回一次.

我哪里错了?

pet*_*erm 5

恕我直言,你的问题与Laravel无关,因为你的基本SQL查询不正确.因为如果您有多个相同品牌的飞机类型,您的查询会多次获取品牌信息(如JOIN所述).

  1. 首先,您不需要加入,aircraft_classes因为您正在过滤aircraft_classes_id
  2. 其次,以获得不同的品牌列表中,您可以选择使用DISTINCTGROUP BY

您的SQL查询可能如下所示

SELECT id, brand_name 
  FROM brands 
 WHERE id IN
(
  SELECT DISTINCT brand_id
    FROM aircraft_types
   WHERE aircraft_class_id = 1
);
Run Code Online (Sandbox Code Playgroud)

要么

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;
Run Code Online (Sandbox Code Playgroud)

这是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();
Run Code Online (Sandbox Code Playgroud)

样本输出 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"
  }
}
Run Code Online (Sandbox Code Playgroud)