首页 > 解决方案 > Laravel 查询生成器左连接中的两个表

问题描述

我有以下查询,我正在尝试将其转换为 Laravel 的查询生成器,以便我可以利用自动转义等。

SELECT subjects.name, report_comments.comment
FROM subjects
LEFT JOIN (report_comments, library_comments) ON subjects.id = library_comments.subject_id
AND report_comments.library_comment_id = library_comments.id
AND report_comments.report_id = 1

实际上,查询所说的是“获取所有主题的名称,如果它们有匹配的 report_comment(通过中间library_comments表),则将其与主题一起返回”(对于给定的标准,主题有一个或零个 report_comments) . 如果我直接在 MySQL 中运行它并返回我期望的结果,则该查询有效。目前report_comment.report_id = 1是硬编码的,但最终将成为一个占位符,以便report_id可以传入任何内容。

到目前为止,我已经设法得到:

DB::table('subjects')->select(['subjects.name', 'report_comments.comment'])->leftJoin('report_comments', function ($join) {
$join->on('subjects.id', '=', 'library_comments.subject_id')
->on('report_comments.library_comment_id', '=', 'library_comments.id')
->on('report_comments.report_id', '=', '1');
})

如果我添加toSql结果是:

select `subjects`.`name`, `report_comments`.`comment` from `subjects` left join `report_comments` on `subjects`.`id` = `library_comments`.`subject_id` and `report_comments`.`library_comment_id` = `library_comments`.`id` and `report_comments`.`report_id` = `1`

这几乎是我想要的,只是它失败了,因为library_comments根本没有提到该表:

Illuminate/Database/QueryException with message 'SQLSTATE[42S22]: Column not found: 1054 Unknown column 'library_comments.subject_id' in 'on clause' (SQL: select `subjects`.`name`, `report_comments`.`comment` from `subjects` left join `report_comments` on `subjects`.`id` = `library_comments`.`subject_id` and `report_comments`.`library_comment_id` = `library_comments`.`id` and `report_comments`.`report_id` = `1`)'

我需要做的是告诉leftJoin函数report_comments and library_comments,但似乎没有任何方法可以做到这一点。我试过:

leftJoin(['report_comments', 'library_comments'], function($join)

猜测 Laravel 可能会将一组表名转换为(report_comments, library_comments),但这不起作用并给了我以下警告:

PHP Notice:  Array to string conversion in /home/paul/sites/report-assistant/vendor/laravel/framework/src/Illuminate/Database/Grammar.php on line 39

有没有办法将多个表传递到leftJoin,或者我需要完全重写查询才能使用 Laravel 的查询构建器?

我使用的是laravel/framework5.8.21 版本,我的所有依赖项都是最新的 ( composer update && npm update)。

标签: phpmysqllaravel

解决方案


采用BD::raw

像这样写查询,它会工作

 DB::table('subjects')->select(['subjects.name, report_comments.comment'])->leftJoin(DB::raw('(report_comments, library_comments)'), function ($join) {
$join->on('subjects.id', '=', 'library_comments.subject_id')
->on('report_comments.library_comment_id', '=', 'library_comments.id')
->on('report_comments.report_id', '=', '1');
})

推荐阅读