Как реализовать GROUP_CONCAT в классе модели Laravel? - PullRequest
0 голосов
/ 21 мая 2018

Я использую функцию GROUP_CONCAT для получения нескольких путей к фотоизображениям для выбранного профессионала в Laravel.Код находится в модельном классе.Сегмент кода выглядит следующим образом:

$professionals = DB::table('member_professional')
    ->select("member_professional.*",
        DB::raw("(GROUP_CONCAT(DISTINCT photos.picture_path SEPARATOR ',')) as 'photos'"))
    ->join('member','member_professional.member_id_fk','=','member.member_id')
    ->join('photos','photos.member_fk','=','member.member_id')
    ->leftjoin('locations','member.city','=','locations.location_id');

        if ($professionals_type != '') {
                     $professionals = $professionals->where('member_professional.biz_category','=',$professionals_type);
        }

        if ($location != '') {
                     $professionals = $professionals->where('member.city','=',$location);
        }

    $professionals = $professionals->where('member.member_type','=',2); 
    $professionals = $professionals->groupBy('member_professional.member_id_fk')
    ->paginate(20);

Когда я запускаю его на промежуточном сервере: http://dev.interioradditions.pk/allProfessionals выдает ошибку:

SQLSTATE [42000]:Синтаксическая ошибка или нарушение прав доступа: 1055 'interior_dev_db.member_professional.biz_name' отсутствует в GROUP BY (SQL: выберите member_professional. *, (GROUP_CONCAT (DISTINCT photos.picture_path SEPARATOR ',')) как 'photos' из member_professional внутреннее соединение member в member_professional. member_id_fk = member. member_id внутреннее объединение photos в photos. member_fk = member. member_id левое соединение locations в member. city = locations. location_id, где member. member_type = 2 сгруппировать по member_professional. member_id_fk предел смещения 20 0)

Принимая во внимание, когда яИзвлеките встроенный SQL-запрос из приведенного выше оператора и выполните через PHPMyAdmin, он работает нормально и дает ожидаемый результат.Пожалуйста, помогите узнать, что не так в запросе модели.

Спасибо!

Ответы [ 2 ]

0 голосов
/ 22 мая 2018

Что я предпочитаю проходить через подход laravel, определяя ваши модели и отношения между ними

class MemberProfessional extends Model
{  
    public function member()
    {
        return $this->hasMany('App\Member', 'member_id', 'member_id_fk');
    }
}

class Member extends Model
{
    public function photos()
    {
        return $this->hasMany('App\Photos', 'member_fk', 'member_id');
    }    
    public function locations()
    {
        return $this->hasMany('App\Locations', 'location_id', 'city');
    }   
    public function member_professional()
    {
        return $this->belongsTo('App\MemberProfessional', 'member_id_fk');
    }   
}

class Photos extends Model{
//...
}

class Locations extends Model{
//...
}

И тогда вы можете написать простой красноречивый запрос

$professionals = MemberProfessional::with('member.photos');

if ($professionals_type != '') {
    $professionals = $professionals->where('biz_category','=',$professionals_type);
}

if ($location != '') {
    $professionals->whereHas('member', function ($query) use ($location) {
                $query->where('city', '=', $location);
                  });
}
    $professionals->whereHas('member', function ($query) use ($location) {
                $query->where('member_type', '=', 2);
                  })
                  ->paginate(20);

Теперь для каждой строки вы будетеиметь коллекцию связанных Photos объектов модели

0 голосов
/ 22 мая 2018

В соответствии с новым выпуском режим ONLY_FULL_GROUP_BY по умолчанию включен, и вам нужно использовать полное выражение GROUP BY, так как все столбцы, присутствующие в вашем списке выбора (кроме агрегированных), должны присутствовать в GROUP BY, как

select a,b, count(c)
from table
group by a,b

В вашем случае вам нужно указать, какие столбцы вам нужны из member_professional например

$professionals = DB::table('member_professional as mp')
    ->select('mp.member_id_fk', 'mp.col1',  'mp.col2',  'mp.col3', DB::raw("(GROUP_CONCAT(DISTINCT p.picture_path SEPARATOR ',')) as 'photos'"))
    ->join('member as m','mp.member_id_fk','=','m.member_id')
    ->join('photos as p','p.member_fk','=','m.member_id')
    ->leftjoin('locations','m.city','=','locations.location_id');

if ($professionals_type != '') {
    $professionals = $professionals->where('mp.biz_category','=',$professionals_type);
}

if ($location != '') {
    $professionals = $professionals->where('m.city','=',$location);
}
$professionals = $professionals->where('m.member_type','=',2)
    ->groupBy('mp.member_id_fk', 'mp.col1',  'mp.col2',  'mp.col3')
    ->paginate(20);

Также обратите внимание на использование GROUP_CONCAT "Результат урезается до максимальной длины, которая равназадается системной переменной group_concat_max_len, значение которой по умолчанию равно 1024. Значение может быть установлено выше, хотя эффективная максимальная длина возвращаемого значения ограничена значением max_allowed_packet ".

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