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');
我有以下查询:
$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');