2013-03-15 2 views
3

Я пытаюсь оптимизировать свой код, в котором я генерирую статистику за последние семь дней.Laravel & multiple count query using Eloquent

В настоящее время я использую 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; 
} 

Я знаю, что можно сгруппировать запросы в SQL, используя схожий синтаксис, как описано here; то, что я хотел бы знать, это если можно сделать то же самое, используя красноречиво/свободно в Laravel, или это возможно только с использованием необработанных запросов?

EDIT: Я не знаю, нужно ли уточнять, но это вопрос Laravel 3.

ответ

5

Всякий раз, когда вы вызываете статический метод в классе модели, он возвращает запрос Fluent, такой как DB::table('yourmodeltable')->method. Если вы помните об этом, вы скоро поймете, что можно выполнить любой запрос с помощью моделей 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 

Edit:

Предложенный подход выше возвратов экземпляров красноречивый модели, которая может показаться странным, особенно если вы 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); 
} 
+0

благодарит за отзыв, позвольте мне сообщить об этом и сообщить об этом. – twaambo

+0

Я обновил ответ с помощью запроса, который я наконец использовал. Еще раз спасибо Vinícius. – twaambo

+0

group_by() и order_by() не работают для меня. Мне пришлось использовать groupBy() и orderBy(). –