Я думаю, что все наоборот, у вас нет 24 групп. Вы получаете 24 элемента в первой группе. Эта конфигурация приводит к следующему запросу:
SELECT
COUNT(*) AS 'aggregate',
`name_id`
FROM `names_to_options`
WHERE EXISTS(
{your $havingRaw sub-query}
)
GROUP BY `name_id`;
То, что вы в итоге получите, будет выглядеть примерно так:
+---------------+---------+
| aggregate | name_id |
+---------------+---------+
| 24 | 1 |
+---------------+---------+
| 5 | 2 |
+---------------+---------+
| 30 | 3 |
+---------------+---------+
| ... and so on | 4 |
+---------------+---------+
Query\Builder
просто не понимает, что вы можете получить более одного результата, если задействован count()
.
Вы были довольно близки к правильному ответу, хотя сами.
$namesIdsCount = DB::table('names_to_options')
->select('name_id')
->groupBy('name_id')
->havingRaw($having)
->get();
get()
возвращает Eloquent\Collection
, потомок Support\Collection
, который имеет собственную версию метода count . Итак, ваш ответ просто:
$namesIdsCount = DB::table('names_to_options')
->select('name_id')
->groupBy('name_id')
->havingRaw($having)
->get()
->count();
Если вы действительно хотите, чтобы это происходило в MySQL, запрос, который вы хотите выполнить, будет выглядеть так:
SELECT COUNT(*) FROM (
SELECT
`name_id`
FROM `names_to_options`
WHERE EXISTS(
{your $havingRaw sub-query}
)
GROUP BY `name_id`
) AS temp;
Для этого вы можете сделать это:
$query = DB::table('names_to_options')
->select('name_id')
->groupBy('name_id')
->havingRaw($having);
$sql = $query->toSql();
$values = $query->getBindings();
$count = DB::table(DB::raw('('.$sql.') AS `temp`'))
->selectRaw("COUNT(*) AS 'aggregate'", $values)
->first()
->aggregate;
Производительность MySQL может немного понизиться, когда он просит написать временные таблицы, поэтому вам придется поэкспериментировать, чтобы выяснить, какой вариант быстрее.