Laravel 5.2 - 在子查询上使用 Left Join 时出现奇怪的结果

Laravel 5.2 - Odd Results When using Left Join on Subquery

我有以下查询:

$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 命令行中粘贴和 运行ning 来测试上面的查询时,我得到了预期的结果,即对于有图像的产品,图像的 file_path 不为空。当我在 MySQL 命令行中 运行 时,唯一的区别是我没有对 subquery.min_created_at 进行任何绑定——我只是替换了 ? subquery.min_created_at

查询为什么会这样。如果我删除第二个左连接,它可以正常工作,但我无法 select 第一个创建的图像加载,例如执行以下操作会给我 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);

理想情况下,我想让我的原始查询正常工作 - 感谢您的帮助。

您正在使用 ->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');