Счетчик не работает должным образом в Laravel Query Builder - PullRequest
0 голосов
/ 09 ноября 2018

Я пытаюсь узнать, сколько имен в базе данных. Для этого я использую Query Builder следующим образом:

$namesIdsCount = DB::table('names_to_options')
    ->select('name_id')
    ->groupBy('name_id')
    ->havingRaw($having)
    ->count();

Is говорит, что 24, что не правильно, потому что если я напишу код, подобный этому:

$namesIdsCount = DB::table('names_to_options')
    ->select('name_id')
    ->groupBy('name_id')
    ->havingRaw($having)
    ->get();

объект результата содержит 247 элементов, что является правильным. Я пытался играть с пропустить / взять, но до сих пор нет результатов. Где я не прав? Спасибо за любую помощь.

Ответы [ 2 ]

0 голосов
/ 09 ноября 2018

Я думаю, что все наоборот, у вас нет 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 может немного понизиться, когда он просит написать временные таблицы, поэтому вам придется поэкспериментировать, чтобы выяснить, какой вариант быстрее.

0 голосов
/ 09 ноября 2018

Инуяки прав

(id, name_id),

(1,1),

(2,1)

(3,2),

(4,3)

Есть четыре строки, поэтому метод get () вернет 4 строки

но есть три группы, если вы используете groupBy [name_id]

1 (1,1)

2 (2)

3 (3)

теперь счет вернет 3

надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...