Laravel Eloquent groupBy () І також повертає рахунок кожної групи


106

У мене є таблиця, яка містить серед інших стовпців стовпчик версій браузера. І я просто хочу дізнатися з набору записів, скільки існує кожного типу браузера. Отже, мені потрібно закінчити щось подібне: Усього записів: 10; Internet Explorer 8: 2; Хром 25: 4; Firefox 20: 4. (Все додається до 10)

Ось мої два пенси:

$user_info = Usermeta::groupBy('browser')->get();

Звичайно, що просто містять 3 браузери, а не кількість кожного. Як я можу це зробити?

Відповіді:


213

Це працює для мене:

$user_info = DB::table('usermetas')
                 ->select('browser', DB::raw('count(*) as total'))
                 ->groupBy('browser')
                 ->get();

1
Чудово! Просто додав "браузер" до вибраного таким чином: виберіть ("браузер", ...) і отримав усе необхідне. Ти добрий, ти! youtube.com/watch?v=ravi4YtUTxo
kJamesy

Дякую. Але чому це не працює при використанні з такими моделями, як User :: select ('країна', DB :: raw ('count (*)) як загальний') -> otherMethods ()?
doncadavona

1
+ v. використовувати \ DB замість DB на контролерах
Amit Bera

@AmitBera, ти можеш пояснити причину ?, будь ласка
JCarlosR

8
Чи є якась особлива причина, чому ви віддаєте перевагу DB::table('usermetas')->..більше Usermeta::..?
Адам


22

Дякую Антоніо,

Я щойно додав listsкоманду в кінці, тому вона поверне лише один масив із ключем і підрахуванням:

Laravel 4

$user_info = DB::table('usermetas')
             ->select('browser', DB::raw('count(*) as total'))
             ->groupBy('browser')
             ->lists('total','browser');

Laravel 5.1

$user_info = DB::table('usermetas')
             ->select('browser', DB::raw('count(*) as total'))
             ->groupBy('browser')
             ->lists('total','browser')->all();

Laravel 5.2+

$user_info = DB::table('usermetas')
             ->select('browser', DB::raw('count(*) as total'))
             ->groupBy('browser')
             ->pluck('total','browser')->all();

1
Дякую. Одна примітка: -> все () у прикладі 5.1 слід видалити, оскільки ви вже перелічуєте результати.
Пім

1
list()застаріло і перейменовано на pluck() laravel.com/docs/5.2/upgrade#upgrade-5.2.0
Код Аруна

12

Якщо ви хочете отримати колекцію, групуйте і підраховуйте:

$collection = ModelName::groupBy('group_id')
->selectRaw('count(*) as total, group_id')
->get();

Ура!


9

Працює так само, трохи охайніше. getQuery()просто повертає основний конструктор, який вже містить посилання на таблицю.

$browser_total_raw = DB::raw('count(*) as total');
$user_info = Usermeta::getQuery()
                     ->select('browser', $browser_total_raw)
                     ->groupBy('browser')
                     ->pluck('total','browser');

5
  1. відчинено config/database.php
  2. Знайдіть strictключ у mysqlналаштуваннях підключення
  3. Встановіть для значення значення false

1

Спробуйте з цим

->groupBy('state_id','locality')
  ->havingRaw('count > 1 ')
  ->having('items.name','LIKE',"%$keyword%")
  ->orHavingRaw('brand LIKE ?',array("%$keyword%"))

2
Хоча це може дати відповідь на запитання, краще пояснити основні частини відповіді та, можливо, в чому була проблема з кодом OP.
пірхо

1

Ось більш Laravel спосіб обробляти групу без необхідності використовувати необроблені оператори.

$sources = $sources->where('age','>', 31)->groupBy('age');

$output = null;
foreach($sources as $key => $source) {
    foreach($source as $item) {
        //get each item in the group
    }
    $output[$key] = $source->count();
}

7
Це пам'ять і обробка голодних.
doncadavona

Те саме pb пам'яті для мене
Вінс

0

Якщо ви хочете отримати відсортовані дані, використовуйте це також

$category_id = Post::orderBy('count', 'desc')->select(DB::raw('category_id,count(*) as count'))->groupBy('category_id')->get();

0
$post = Post::select(DB::raw('count(*) as user_count, category_id'))->groupBy('category_id')->get();

Це приклад, який підраховує кількість публікацій за категоріями.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.