使用Laravel查询构造器和LEFT JOIN删除行

4
如何在一条带有左连接的查询中从多个表中删除行。
查询语句:
DELETE `deadline`, `job` FROM `deadline` LEFT JOIN `job` ....

因此,我这样尝试它:
DB::table('deadline', 'job')
    ->leftJoin('job', 'deadline.id', '=', 'job.deadline_id')
    ->where('deadline.id', $id)
    ->delete();

似乎 Laravel 不支持在左连接中从多个表中删除数据。

是否有官方支持的方法或解决方案?


2
不确定这是否是 Eloquent 的新功能,但现在它可以工作了。我能够使用左连接查询进行删除。 - Matt K
4个回答

6

看起来我的方式不可行。所以我就这样做了。

$q = 'DELETE deadline, job FROM deadline LEFT JOIN job ...where deadline.id = ?';        
$status = \DB::delete($q, array($id));

文档:http://laravel.com/docs/database#running-queries

这个链接是关于在Laravel中运行查询的文档。


1
为了使laravel允许在删除操作中进行联接,很简单 - 你只需要修改Illuminate\Database\Query\Grammars\Grammar中的compileDelete函数为以下内容即可:
public function compileDelete(Builder $query)
{
    $table = $this->wrapTable($query->from);

    $components = implode(' ', array(
        is_array($query->joins) ? $this->compileJoins($query, $query->joins) : '',
        is_array($query->wheres) ? $this->compileWheres($query, $query->wheres) : '',
        is_array($query->limit) ? $this->compilelimit($query, $query->limit) : '',
        is_array($query->offset) ? $this->compileOffset($query, $query->offset) : ''
    ));

    return trim("delete $table from $table ".$components);
}

然后 ->delete() 会按照你的预期工作。我已经将其添加为拉勾维尔框架存储库的pull request,希望这可能会合并到下一个版本中 - 只需等待。


是否有计划在Laravel中实现这样的更改?因为这真的很遗憾,在文档中也没有提到,也不会抛出异常。 - Umair Ahmed
他们实现了这个功能,可以在这里查看。然而这在 OP 的情况下编译为以下 SQL: delete from "deadline" where "rowid" in (select "deadline"."rowid" from "deadline" left join "job" on "deadline"."id" = "job"."deadline_id" where "deadline"."id" = ?),假设只应用了table()的第一个参数。 - luukvhoudt

1

DB::table(DB::raw('deadline, job')) 可能有效。如果无效,则需要手动编写SQL并通过 DB::statement() 调用。


0
$query = 'DELETE courses,course_contents FROM courses 
          INNER JOIN course_contents ON course_contents.course_id = courses.id  
          WHERE courses.id = ?';

\DB::delete($query, array($id));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接