Laravel&使用Eloquent进行多次计数查询

时间:2013-03-15 16:47:04

标签: mysql laravel 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中的雄辩/流利来做同样的事情,或者只能使用原始查询来做到这一点?

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

1 个答案:

答案 0 :(得分:5)

每当在模型类上调用静态方法时,它都会返回类似DB::table('yourmodeltable')->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 Model的实例,这可能看起来很奇怪,特别是如果你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);
}