【问题标题】:Laravel & multiple count queries using EloquentLaravel 和使用 Eloquent 的多个计数查询
【发布时间】:2013-03-04 11:44:23
【问题描述】:

我正在尝试优化我的代码,其中我生成了过去 7 天的统计信息。

目前我正在使用 eloquent & 查询计数来记录每天的数据,这导致我在一个循环中进行 7 个单独的查询。

示例:

// loop for number of days
for($i = 0; $i < $days; $i++){
    // some logic to set comparitive unix times
    $oldest = $newest - $dayDuration;

    // count number of objects between oldest time and newest time
    $counts[$i] = Object::where('objecttime','>',$oldest)
                          ->where('objecttime','<',$newest)->count();

    // more logic to set comparitive unix times
    $newest = $newest - $dayDuration;
}

我知道可以使用与here 所述类似的语法在 sql 中对查询进行分组;我想知道的是是否可以在 Laravel 中使用 eloquent/fluent 来做同样的事情,还是只能使用原始查询来做到这一点?

编辑:我不知道是否需要澄清,但这是 Laravel 3 的问题。

【问题讨论】:

    标签: mysql laravel eloquent


    【解决方案1】:

    每当您在模型类上调用静态方法时,它都会返回像 DB::table('yourmodeltable')-&gt;method 这样的 Fluent 查询。如果您牢记这一点,您很快就会意识到可以使用 Eloquent 模型进行任何查询。

    现在,为了获得更高的性能,您可以使用 SQL 的DATE() 函数。我下面的示例未经测试,请随时更正。

    // tomorrow -1 week returns tomorrow's 00:00:00 minus 7 days
    // you may want to come up with your own date tho
    $date = new DateTime('tomorrow -1 week');
    
    // DATE(objecttime) turns it into a 'YYYY-MM-DD' string
    // records are then grouped by that string
    $days = Object::where('objecttime', '>', $date)
        ->group_by('date')
        ->order_by('date', 'DESC') // or ASC
        ->get(array(
            DB::raw('DATE(`objecttime`) AS `date`'),
            DB::raw('COUNT(*) as `count`')
        ));
    
    foreach ($days as $day) {
        print($day->date . ' - '. $day->count);
    }
    

    这应该打印如下内容:

    2013-03-09 - 13
    2013-03-10 - 30
    2013-03-11 - 93
    2013-03-12 - 69
    2013-03-13 - 131
    2013-03-14 - 185
    2013-03-15 - 69
    

    编辑:

    上面建议的方法返回 Eloquent 模型的实例,这可能看起来很奇怪,特别是如果你 var_dump($days)。你也可以使用 Fluent 的list() 方法来实现同样的事情。

    $date = new DateTime('tomorrow -1 week');
    
    // lists() does not accept raw queries,
    // so you have to specify the SELECT clause
    $days = Object::select(array(
            DB::raw('DATE(`objecttime`) as `date`'),
            DB::raw('COUNT(*) as `count`')
        ))
        ->where('created_at', '>', $date)
        ->group_by('date')
        ->order_by('date', 'DESC') // or ASC
        ->lists('count', 'date');
    
    // Notice lists returns an associative array with its second and
    // optional param as the key, and the first param as the value
    foreach ($days as $date => $count) {
        print($date . ' - ' . $count);
    }
    

    【讨论】:

    • 感谢您的回复,让我给您一个 bash 并报告。
    • 我已经用我最终使用的查询更新了答案。再次感谢维尼修斯。
    • group_by() 和 order_by() 对我不起作用。我不得不使用 groupBy() 和 orderBy()。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-12
    • 2014-10-31
    • 1970-01-01
    • 1970-01-01
    • 2017-11-03
    • 1970-01-01
    相关资源
    最近更新 更多