不能用 PostgreSQL 与 eloquent 分组

Posted

技术标签:

【中文标题】不能用 PostgreSQL 与 eloquent 分组【英文标题】:cannot group with eloquent with PostreSQL 【发布时间】:2018-11-14 23:02:04 【问题描述】:

这是我的 Eloquent 查询:

$visits = Visit::orderBy('date', 'desc')->groupBy('user_id')->get(['date', 'user_id']);

但是 posgreSQL 拒绝查询,告诉我:

SQLSTATE[42803]:分组错误:7 错误:列“visits.date”必须出现在 GROUP BY 子句中或用于聚合函数 LINE 1: select "date", "user_id" from "visits" group by...

当我禁用 ONLY_FULLY_GROUP_BY 时,相同的东西在 mysql 上工作

我该怎么做才能让它发挥作用?如果我不必编辑配置,只需编辑代码,那就太好了。

【问题讨论】:

你可以尝试在configs中关闭严格模式 你为什么将users 分组为user_id?那不是主键吗? 不,不是,我会编辑它,让它更清晰 当每个user_id有多个visits时,你想得到哪个date 我什至可以得到随机日期(如果它与用户的至少一次访问匹配)问题在于错误 【参考方案1】:

这将为每个user_id 选择最新的date

$sub = Visit::select('user_id', DB::raw('max("date") "date"'))->groupBy('user_id');
$sql = '(' . $sub->toSql() . ') as "sub"';
$visits = Visit::join(DB::raw($sql), function($join) 
    $join->on('visits.user_id', 'sub.user_id')
        ->on('visits.date', 'sub.date');
)->orderBy('visits.date', 'desc')->get(['visits.date', 'visits.user_id']);

如果user_iddate 组合有多次访问,则查询将返回所有访问。可以删除重复项,但会使查询更加复杂。 之后删除它们更容易:

$visits = $visits->unique('user_id');

【讨论】:

【参考方案2】:

使用 postgre sql 你可以使用distinct on user_id 并命令你的日期列选择每个 user_id 的最新日期,在 laravel 你可以原始表达式

$visits = Visit::select(DB::raw('distinct on (user_id)'), 'date')
          ->orderBy('date', 'desc')
          ->get();

Demo

【讨论】:

我收到错误:SQLSTATE[42000]: 语法错误或访问冲突:1064 您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 1 行的 'on (user_id), date from visits order by date desc' 附近使用正确的语法(SQL:select distinct on (user_id), date from visits order by date desc) @TutuKaeen 此查询仅对 postgresql 有效,根据您在 Mysql 上运行的错误。请确认您使用的是哪个数据库供应商 Mysql 或 postgresql ? 是的,这是 MySQL,我很抱歉,但 PostreSQL 也会抛出错误:Illuminate\Database\QueryException 并带有消息“SQLSTATE[42601]:语法错误:7 错误:语法错误” , LINE 1: select distinct on (user_id), "date" from "visi... 缺少别名:distinct on (user_id) user_id。并且演示查询仅适用,因为它按user_id AND date 排序。

以上是关于不能用 PostgreSQL 与 eloquent 分组的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Laravel Eloquent 更新 PostgresQL 中 jsonb 列的多个“键”

Laravel Eloquent 如何在 Postgresql 中使用 DATE_FORMAT

laravel eloquent order by specific value with PostgreSQL 数据库

在 Laravel Eloquent Query 中使用 unaccent PostgreSQL 函数

Laravel Eloquent Postgresql Select with Case,然后按 Case 结果过滤

使用 Eloquent 模型的数据类型不匹配