如何在 Laravel 中使用具有多态关系的“group by”?

Posted

技术标签:

【中文标题】如何在 Laravel 中使用具有多态关系的“group by”?【英文标题】:How to use "group by" with a polymorphic relationship in Laravel? 【发布时间】:2017-04-04 23:05:08 【问题描述】:

我有以下关系:

return $this->morphedByMany('App\Models\Movie', 'listable', 'cnt_lists', 'list_id')->withPivot('id', 'order', 'updated_at')->where('movies.has_poster', true)->orderBy('order', 'desc')->withTimestamps();

这种关系产生了这个查询:

select `movies`.*, `cnt_lists`.`list_id` as `pivot_list_id`, `cnt_lists`.`listable_id` as `pivot_listable_id`, `cnt_lists`.`id` as `pivot_id`, `cnt_lists`.`order` as `pivot_order`, `cnt_lists`.`updated_at` as `pivot_updated_at`, `cnt_lists`.`created_at` as `pivot_created_at` from `movies` inner join `cnt_lists` on `movies`.`id` = `cnt_lists`.`listable_id` where `movies`.`has_poster` = '1' and `cnt_lists`.`list_id` in ('3176', '3283', '3285', '3287') and `cnt_lists`.`listable_type` = 'App\Models\Movie' order by `order` desc

这种关系有效,但它为每个列表抓取了很多。我试图限制每个列表只有一个。我最初是在探索take(),但这限制了整个结果集,而不是每个列表的限制。然后我想我可以按cnt_lists.list_id 分组,每个列表都会抓取一个。这似乎让我得到了我正在寻找的东西。下面是对我有用的查询,我只是想弄清楚如何在关系中使用 group by,因为当我添加它时它会破坏关系。

select `movies`.*, `cnt_lists`.`list_id` as `pivot_list_id`, `cnt_lists`.`listable_id` as `pivot_listable_id`, `cnt_lists`.`id` as `pivot_id`, `cnt_lists`.`order` as `pivot_order`, `cnt_lists`.`updated_at` as `pivot_updated_at`, `cnt_lists`.`created_at` as `pivot_created_at` from `movies` inner join `cnt_lists` on `movies`.`id` = `cnt_lists`.`listable_id` where `movies`.`has_poster` = '1' and `cnt_lists`.`list_id` in ('3176', '3283', '3285', '3287') and `cnt_lists`.`listable_type` = 'App\Models\Movie' group by `cnt_lists`.`list_id` order by `order` desc

当我在关系中添加groupBy 时:

return $this->morphedByMany('App\Models\Movie', 'listable', 'cnt_lists', 'list_id')->withPivot('id', 'order', 'updated_at')->where('movies.has_poster', true)->groupBy('cnt_lists.list_id')->orderBy('order', 'desc')->withTimestamps();

我收到以下错误:

select `movies`.*, `cnt_lists`.`list_id` as `pivot_list_id`, `cnt_lists`.`listable_id` as `pivot_listable_id`, `cnt_lists`.`id` as `pivot_id`, `cnt_lists`.`order` as `pivot_order`, `cnt_lists`.`updated_at` as `pivot_updated_at`, `cnt_lists`.`created_at` as `pivot_created_at` from `movies` inner join `cnt_lists` on `movies`.`id` = `cnt_lists`.`listable_id` where `movies`.`has_poster` = 1 and `cnt_lists`.`list_id` in (3176, 3283, 3285, 3287) and `cnt_lists`.`listable_type` = App\Models\Movie group by `cnt_lists`.`list_id` order by `order` desc

由于某种原因,模型App\Models\Movie 不在引号中,因此它破坏了整个查询。如果我手动运行查询,它可以工作,我只需在多态模型中添加引号。即"App\Models\Movie"

【问题讨论】:

你有为此设置的 morphMap 吗?这是否在您的查询停止工作的同时发生了变化? @mopo922 这是一个新查询,所以它从来没有工作过。我有 morphMaps 设置,但不适用于“App\Models\Movie”模型。 @ATLChris 您能否验证您的模型 namespaces 是否以 前导斜杠 保存在数据库中? @atefth 他们不使用前导斜杠保存。 @atefth 它确实产生了相同的 mysql 错误。这个问题是当您使用 group by 时,模型不会被引号括起来。我现在正在查看源代码,因为我认为它是查询生成器中的错误。 【参考方案1】:

我得到了你的问题和答案。根据您的回答,我知道主要问题是“严格模式”,这实际上只是 5.7 默认启用的模式列表。有时我们的人对strict mode 不了解。在https://mattstauffer.co/blog/strict-mode-and-other-mysql-customizations-in-laravel-5-2这个链接,你会得到如何Enabling and disabling strict mode in Laravel 5.2例如

这些设置位于connections.mysql 部分的config/database.php 中。首先,让我们看看启用和禁用“严格”模式:

 'connections' => [
        'mysql' => [
            // Behave like MySQL 5.6
            'strict' => false,

            // Behave like MySQL 5.7
            'strict' => true,
        ]
    ]

我们也可以自定义:

'connections' => [
        'mysql' => [
            // Ignore this key and rely on the strict key
            'modes' => null,

            // Explicitly disable all modes, overriding strict setting
            'modes' => [],

            // Explicitly enable specific modes, overriding strict setting
            'modes' => [
                'STRICT_TRANS_TABLES',
                'ONLY_FULL_GROUP_BY',
            ],
        ]
    ]

谢谢

【讨论】:

【参考方案2】:

好的,原来问题与 MySQL 严格模式有关,其中包括ONLY_FULL_GROUP_BY 模式。

我在 Laravel 级别禁用了严格模式,查询现在按预期工作。只需在数据库配置文件中为您的连接设置strictfalse

'strict' => false,

【讨论】:

以上是关于如何在 Laravel 中使用具有多态关系的“group by”?的主要内容,如果未能解决你的问题,请参考以下文章

如何最好地链接到 Laravel 中的多态关系

如何在laravel中获得多态关系?

如何在 Laravel 中对所有行使用多态关系?

Laravel:多种用户类型的表结构,多态关系

Laravel:Eloquent模型中的多重多态关系

Laravel 5.8多态关系`nullableMorphs`不起作用