You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Laravel Query Builder获取age列唯一的完整行数据

问题:获取age列值唯一的完整行数据

表结构与需求

原表数据:

idagecolor
12blue
33red
45green
55purple

需求:获取所有age列值唯一的行,预期返回:

idagecolor
12blue
33red
45green

尝试过的方法及问题

1. 使用distinct('age')

代码:

$baseQuery = myModel::query()
->select('id', 'age', 'color')
->distinct('age')
->get()

问题:distinct是针对所有选中列的组合去重,并非单独对age列去重。当同时选择id、age、color时,只要这三列的组合不重复就会被保留,因此最终返回了所有行。只有当select仅包含age时,才会实现age列的去重。

2. 使用groupBy('age')

代码:

$baseQuery = myModel::query()
->select('id', 'age', 'color')
->groupBy('age')
->get()

问题:触发MySQL 1055错误:

Syntax error or access violation: 1055 'table.color' isn't in GROUP BY

这是因为MySQL默认开启了ONLY_FULL_GROUP_BY模式,该模式要求GROUP BY子句中必须包含SELECT里所有非聚合函数的列,否则会报错。

解决方案

方法1:临时关闭ONLY_FULL_GROUP_BY模式

在执行查询前修改SQL模式,再执行分组查询:

\DB::statement("SET SQL_MODE=''");
$baseQuery = myModel::query()
->select('id', 'age', 'color')
->groupBy('age')
->get()

注意:关闭ONLY_FULL_GROUP_BY后,MySQL会从每个age分组中随机选取id和color的值,刚好符合预期结果,但如果需要指定选取分组内的某一行(比如最小id对应的行),这种方法的结果不可控。

更严谨的方法:通过子查询指定分组内的目标行

如果需要确保每个age分组返回特定行(比如id最小的行),可以用子查询先获取每个age对应的最小id,再关联原表:

$baseQuery = myModel::query()
    ->select('t.id', 't.age', 't.color')
    ->from('my_table as t')
    ->join(
        myModel::query()->selectRaw('age, min(id) as min_id')->groupBy('age'),
        function ($join) {
            $join->on('t.age', '=', 'age')->on('t.id', '=', 'min_id');
        }
    )
    ->get();

这种方法不需要修改SQL模式,结果更可控,适合需要明确返回分组内特定行的场景。

内容的提问来源于stack exchange,提问作者ThatSWE

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 13:01:04