Laravel: 获取 Eloquent 创建嵌套 SELECT 的正确方法

3

我正在尝试让 Eloquent 生成以下查询:

SELECT *, (SELECT COUNT(comment_id) FROM comment AS c WHERE c.approved=true AND c.blog_fk=b.blog_id) AS comment_count FROM blog AS b

这是结果

blog_id |  title            | author       | blog           | image            | tags    | created             | updated             | comment_count
--------|-------------------|--------------|----------------|------------------|---------|---------------------|---------------------|--------------
     21 | A day..           | dsyph3r      | Lorem ipsum... | beach.jpg        | symf... | 2014-12-22 19:14:34 | 2014-12-22 19:14:34 | 2
     22 | The pool ..       | Zero Cool    | Vestibulum ... | pool_leak.jpg    | pool,.. | 2011-07-23 06:12:33 | 2011-07-23 06:12:33 | 10
     23 | Misdirection...   | Gabriel      | Lorem ipsum... | misdirection.jpg | misd... | 2011-07-16 16:14:06 | 2011-07-16 16:14:06 | 2
     24 | The grid ...      | Kevin Flynn  | Lorem commo... | the_grid.jpg     | grid... | 2011-06-02 18:54:12 | 2011-06-02 18:54:12 | 0
     25 | You're either ... | Gary Winston | Lorem ipsum... | one_or_zero.jpg  | bina... | 2011-04-25 15:34:18 | 2011-04-25 15:34:18 | 2

目前,我是通过使用DB::select(DB::raw())���运行的,这可能不是正确的方法。

问题是,如何正确地让Eloquent生成生成这些结果的查询?


我的回答问题应该能帮到你。正如我在评论中提到的,明天我会提供一些更新的代码,让你可以向计数语句添加约束条件(例如,“approved = true”)。但是,这需要正确设置关系。 - patricus
@patricus,你尝试得太努力了,最好阅读这篇文章http://softonsofa.com/tweaking-eloquent-relations-how-to-get-hasmany-relation-count-efficiently - Jarek Tkaczyk
@JarekTkaczyk 这取决于需求是什么。我绝对喜欢您使用关系的方法,并且会在其他情况下使用该方法,但它并没有完全回答所提出的问题。有些情况下,人们可能需要将关系计数添加到初始SQL语句中,而不仅仅是在模型加载后立即获得计数。例如,数据库服务器根据计数对结果进行排序,就像我在上面的评论中指出的datatables问题一样。 - patricus
@patricus 是的,那是另一回事,只涉及到数据表格(或一般情况下按关系排序),这不是这里的情况。 - Jarek Tkaczyk
@JarekTkaczyk 不,这里不是按计数排序。然而,从问题中我们所知道的是用户想要计数作为初始SQL语句的一部分。如果这是必须遵循的约束条件,那么你的解决方案就行不通。如果这是可以放宽的限制条件,那么你的解决方案就很好。 - patricus
显示剩余2条评论
2个回答

6

请使用以下链接替代:http://softonsofa.com/tweaking-eloquent-relations-how-to-get-hasmany-relation-count-efficiently

对于嵌套的select/join语句,您需要使用以下内容:

$sub = Comment::selectRaw('count(comment_id) as count')
       ->where('approved', '?')
       ->where('comment.blog_fk', '?')
       ->toSql();

Blog::selectRaw(DB::raw("blog.*, ({$sub}) as comment_count"))
       ->setBindings([true, DB::raw('blog.blog_id')], 'select')
       ->get();

或者将所有内容放置在selectRaw中。

1
你可以使用 Laravel Eloquent 进行预加载。我建议你学习 Laravel 关系模型,以充分利用 Laravel 的优势。顺便说一下,一旦你在这两个模型之间定义了关系,下面的代码可能适用于你。
$users = Blog::with(array('Comment' => function($query)
{
    $query->
    where('approved','=',true)->
    select(DB::raw('Count(comment_id) as comment_count'));

}))->get();

闭包,但你还需要选择“外键”,否则它将无法工作。 - Jarek Tkaczyk
只要按照表中的命名规范进行操作,它就能够正常工作。 - Sameer Shaikh
不,这与命名无关。请阅读此链接:http://stackoverflow.com/a/25907624/784588 - Jarek Tkaczyk

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