Laravel 5.2 - 在子查询

时间:2017-08-04 14:20:22

标签: mysql laravel-5.2 left-join laravel-query-builder

我有以下查询:

$products = Product::leftJoin(DB::Raw('(SELECT imageable_id, MIN(created_at) as min_created_at
                               FROM images WHERE imageable_type = "App\\\Product"
                               GROUP BY imageable_id) AS subquery'), function($join)  {
                                $join->on('subquery.imageable_id', '=', 'products.id');
                        })
                        ->leftJoin('images', function ($join) {
                            $join->on('images.imageable_id', '=', 'subquery.imageable_id')
                                ->where('images.created_at', '=', 'subquery.min_created_at');})
                       ->select('products.*', 'images.file_path')
                       ->paginate(5);

当我死掉并转储查询日志时,上面的翻译如下:

"query" => """
  select `products`.*, `images`.`file_path` from `products`
  left join (SELECT imageable_id, MIN(created_at) as min_created_at
              FROM images WHERE imageable_type = "App\\Product"
              GROUP BY imageable_id) AS subquery on `subquery`.`imageable_id` = `products`.`id` 
  left join `images` on `images`.`imageable_id` = `subquery`.`imageable_id` and `images`.`created_at` = ? 
  limit 5 offset 0
  """
 "bindings" => array:1 [
      0 => "subquery.min_created_at"

 ]

哪个看起来不对,但我不确定为什么为subquery.min_created_at添加了绑定

现在,当我在laravel images中执行上述查询时,file_path总是为空,但显然我知道有相关的图像。当我通过粘贴它并直接在MySQL命令行中运行来测试上述查询时,我得到预期的结果,即对于具有图像的产品,图像的file_path不为空。我在MySQL命令行中运行的唯一区别是我没有对subquery.min_created_at进行任何绑定 - 我只是替换了?与subquery.min_created_at

为什么查询以这种方式表现的任何想法。如果我删除第二个左连接它可以正常工作,但是我无法选择要加载的第一个创建的图像,例如,执行以下操作给我file_path:

$products =  Product::leftJoin(DB::Raw('(SELECT imageable_id, file_path
                               FROM images WHERE imageable_type = "App\\\Product"
                               GROUP BY imageable_id) AS subquery'), function($join)  {
                                $join->on('subquery.imageable_id', '=', 'products.id');
                        })
                        ->select('products.*', 'subquery.file_path')
                       ->paginate(5);

理想情况下,我想让我原来的查询工作 - 任何帮助表示感谢。

1 个答案:

答案 0 :(得分:1)

您正在使用->where()作为第二个加入条件:

->where('images.created_at', '=', 'subquery.min_created_at')

这会生成

and `images`.`created_at` = ?

绑定的目的。

相反,您应该使用->on();

$join->on('images.imageable_id', '=', 'subquery.imageable_id')
     ->on('images.created_at', '=', 'subquery.min_created_at');