laravel 中的 Groupby 将分组的项目留在对象中

Posted

技术标签:

【中文标题】laravel 中的 Groupby 将分组的项目留在对象中【英文标题】:Groupby in laravel leave grouped items in object 【发布时间】:2018-06-30 10:50:09 【问题描述】:

对,不知道是我做错了什么还是 Laravel 中的 Illuminate\Database 有问题。

我的代码:

$sth = Insect::leftJoin('types', 'types.id', '=', 'families.type_id')
            ->select('types.name as types','families.id','families.name')
            ->get()
            ->groupBy('types');

groupBy 之前的结果是:

[

    "types": "moths",
    "id": 1,
    "name": "Bombycidae"
,

    "types": "moths",
    "id": 2,
    "name": "Brahmaeidae"
,

    "types": "moths",
    "id": 3,
    "name": "Cossidae"
,

    "types": "larvas",
    "id": 6,
    "name": "test"
]

但是使用 groupBy:


"moths": [
    
        "types": "moths",
        "id": 1,
        "name": "Bombycidae"
    ,
    
        "types": "moths",
        "id": 2,
        "name": "Brahmaeidae"
    ,
    
        "types": "moths",
        "id": 3,
        "name": "Cossidae"
    
],
"larvas": [
    
        "types": "larvas",
        "id": 6,
        "name": "test"
    
]

所以我的问题是,我想摆脱对象中的那种类型...

有什么想法吗?

【问题讨论】:

那么不要把它们放在select中。 那么结果是:i.imgur.com/CkqohJ3.png 您可以尝试在 group by 之后添加 ->get() 吗?会发生什么? 那么我将只得到每种“类型”lnik to code 的 1 个结果 好的,你可以尝试添加 orderBy 两次,第一次是 ID,第二次是“types”。参考link 并且没有 groupBy 【参考方案1】:

好吧,首先你要做的是在结果集合上调用groupBy,这与命名非常糟糕的GROUP BY mysql 查询子句无关(不相关,但值得注意)。

您可以将结果映射到您需要的内容:

 $sth = Insect::leftJoin('types', 'types.id', '=', 'families.type_id')
                    ->select('types.name as types','families.id','families.name')
                    ->get()
                    ->groupBy('types')->map(function ($group) 
                          return $group->map(function ($value) 
                                return [ "id" => $value->id, "name" => $value->name ];
                          );
                     );

【讨论】:

"message": "'on Clause' 中的未知列 'families.family_id'" 我刚刚在您现有的(工作?)查询中添加了map。这不会导致该消息。在您的问题的查询中,您似乎确实缺少与 families 表的连接。你的意思是写insects.family_id 吗? my code,所以我设置为注释的第一个代码有效,但是你的代码抛出了那个错误...... :( 其实你是对的,我的错(在 leftJoin 中)我没有更改 type_id 上的 family_id,你猜怎么着,IT WORKS :) 结果link to code 你能把代码 'families.family_id' 改成 'families.type_id' 吗?【参考方案2】:

您可以删除选择类型,而是执行以下操作:

$sth = Insect::leftJoin('types', 'types.id', '=', 'families.family_id')
    ->select('families.id','families.name')
    ->groupBy('insects.id', 'types.name')
    ->get();

此外,要查看实际的原始查询,您可以使用以下内容

$sth = Insect::leftJoin('types', 'types.id', '=', 'families.family_id')
    ->select('families.id','families.name')
    ->groupBy('insects.id', 'types.name')
    ->toSql();

dd($sth);

您正在选择要在对象中使用的列,因此如果您从 select 语句中删除它,它将不再显示在您的对象中,您还可以将类型添加到类型模型中的 $hidden 输入中,如下所示:

/**
 * The attributes that should be hidden for arrays.
 *
 * @var array
 */
protected $hidden = [
    'name',
];

laravel 中的分组:https://laravel.com/docs/5.5/queries#ordering-grouping-limit-and-offset

从数组中隐藏行:https://laravel.com/docs/5.5/eloquent-serialization#hiding-attributes-from-json

【讨论】:

"message": "'on Clause' 中的未知列 'families.family_id'" link to code 但是:受保护的 $hidden = ['types'];帮助,非常感谢你:) 您可以在查询中添加 ->toSql() 并为我发布结果吗? 然后我收到一个纯文本,例如:“select families.id, families.name from families left join types on types.id = families.family_id group by insects.id, types.name" 查询是否在最上面,使用 get() 而不是 toSql();?

以上是关于laravel 中的 Groupby 将分组的项目留在对象中的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 查询构建器 - 如何按别名分组,或进行原始 groupBy

Laravel 选择列,然后按日期对列值进行分组

在 Laravel 中按多列分组

laravel groupby 与数组

如何为 Laravel ORM 中每个组中的单个项目执行 groupBy()

Laravel 查询 - 加入和分组