【问题标题】:How to implement GROUP_CONCAT in Laravel model class?如何在 Laravel 模型类中实现 GROUP_CONCAT?
【发布时间】:2018-10-30 22:38:35
【问题描述】:

我正在使用 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: select member_professional.*, (GROUP_CONCAT(DISTINCT photos.picture_path SEPARATOR ',')) as 'photos' 从member_professional 内连接member member_professional.member_id_fk = member.member_id 内连接photos photos.member_fk = member.@987 左加入locationsmember.city = locations.location_id 其中member.member_type = 2 分组 member_professional.member_id_fk 限制 20 偏移量 0)

而当我从上面的语句中提取构建的 sql 查询并通过 PHPMyAdmin 执行时,它运行良好并给出了预期的结果。请帮助了解模型查询中的问题。

谢谢!

【问题讨论】:

  • 您在滥用 group by 子句
  • 如果你设置模型和关系会很容易,然后 eloquent 会完成剩下的工作,不需要GROUP_CONCAT
  • 能否请您帮助如何在这种特殊情况下使用 group by 子句?

标签: mysql laravel


【解决方案1】:

我更喜欢通过定义模型和它们之间的关系来通过 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 模型对象的集合

【讨论】:

  • 太棒了。看起来是使用 Laravel 模型结构的最佳(和干净)解决方案。抱歉,我正忙于其他一些任务。无论如何,我将应用此解决方案并让您知道。非常感谢您的帮助。 :)
【解决方案2】:

根据新版本,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_pa​​cket”值的约束。

【讨论】:

    猜你喜欢
    • 2016-02-28
    • 1970-01-01
    • 2017-10-13
    • 1970-01-01
    • 1970-01-01
    • 2020-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多