Laravel查询构建器中左连接的两个表

时间:2019-06-07 13:25:20

标签: php mysql 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 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/framework版本5.8.21,我的所有依赖关系都是最新的(composer update && npm update)。

3 个答案:

答案 0 :(得分:1)

使用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');
})

答案 1 :(得分:0)

不知道这是否行得通,但我认为它将沿着这些思路发展,希望您能从中得到一些帮助。

基本上添加了一个检查,以查看该关系是否存在(如果确实存在),然后将其加入。

public bool IsEmailUnique(string email)
{
    return this._apiService.GetCustomerByEmail(email) != null;
}

答案 2 :(得分:0)

经过一番修补,我设法分两部分找到答案:

首先,我必须调整连接的这一部分:

  <script type="text/javascript">
  function BLINK(){
  var t = null;
  function blink() {
      var obj = $('input[id="IP"][value=response[i]]') . <---- here
      obj.addClass("blink-class");
      t = setTimeout(function () {
          obj.removeClass("blink-class");
          t = setTimeout(function () {
              blink(IP);
          }, 550);
      }, 550);
  }
  blink(IP);
  t = setTimeout(function () {
      clearTimeout(t);
  }, 5000);
}

并替换为:

on('report_comments.report_id', '=', '1')

如果我不这样做,Laravel会用反引号引号where('report_comments.report_id', '=', '1') ,从而使MySQL将其解释为列名。

另一种更改是使用1,我试图避免这种情况,但是我认为在这种情况下它并不算太糟糕,因为我传递的是硬编码字符串而不是用户输入(或受用户输入)。 DB::raw现在看起来像:

leftJoin