Группа Laravel по запросу - PullRequest
       7

Группа Laravel по запросу

0 голосов
/ 15 октября 2018

Я получил этот запрос в Laravel:

return $this->hasMany(Facility::class)
            ->select("id", "port_id", "facility",
                DB::raw("(SELECT count('*') FROM port_facilities
                                    WHERE has_it = 1) as has_it_true"),
                DB::raw("(SELECT count('*') FROM port_facilities
                                    WHERE has_it = 0) as has_it_false"))
            ->groupBy('facility');

Он подсчитывает, есть ли у порта определенные возможности.Проблема, которая у меня сейчас есть, в том, что groupBy не работает.Это все, а не grouping по средствам.Любая идея, как я мог это исправить?

Ответы [ 2 ]

0 голосов
/ 15 октября 2018

Здесь необходимо использовать условное агрегирование:

return $this->hasMany(Facility::class)
    ->select("facility",
        DB::raw("COUNT(CASE WHEN has_it = 1 THEN 1 END) AS has_it_true"),
        DB::raw("COUNT(CASE WHEN has_it = 0 THEN 1 END) AS has_it_false"))
    ->groupBy('facility');

Это будет соответствовать следующему необработанному запросу MySQL:

SELECT
    facility,
    COUNT(CASE WHEN has_it = 1 THEN 1 END) AS has_it_true,
    COUNT(CASE WHEN has_it = 0 THEN 1 END) AS has_it_false
FROM port_facilities
GROUP BY
    facility;

Обратите внимание, что я не включил id и port_id в предложении SELECT, поскольку MySQL может не принимать эти столбцы.В общем, при выполнении GROUP BY facility мы можем выбрать только facility и совокупность столбцов, отличных от facility.

0 голосов
/ 15 октября 2018

Вы смешиваете два компонента Laravel здесь.1 - определение отношения с Eloquent, а другое - с использованием QueryBuilder.

Начиная с запроса, ваш «адаптированный» запрос должен выглядеть следующим образом:

Facility::select("id", "port_id", "facility",
                DB::raw("(SELECT count('*') FROM port_facilities
                                    WHERE has_it = 1) as has_it_true"),
                DB::raw("(SELECT count('*') FROM port_facilities
                                    WHERE has_it = 0) as has_it_false"))
            ->groupBy('facility')->get();

Если вы хотите установить отношение, то в модели вы хотите указать отношениевы должны сделать что-то вроде перечисленного в документации:

https://laravel.com/docs/5.7/eloquent-relationships#defining-relationships

Совет: не count('*'), если вам действительно не нужно (вы можете сосчитать один столбец или паруи не увеличивайте производительность), не смешивайте QueryBuilder с Eloquent, если вам не нужно, и

...