Laravel hasmanythrough 或 mysql group by

Posted

技术标签:

【中文标题】Laravel hasmanythrough 或 mysql group by【英文标题】:Laravel hasmanythrough or mysql groupby 【发布时间】:2020-05-21 03:41:51 【问题描述】:

我有三张桌子

类别

id | category_name | created_at | updated_at

个人资料

id | category_id | profile_name | created_at | updated_at

照片

id | profile_id | photo_name | photo_path | photo_type | created_at | updated_at

现在我需要按类别列出照片,并且每个个人资料中只需要按 photo_type 列出一张照片

我尝试过使用 hasManyhrough,但按 created_at 递减不工作

public function categoryPhotos()
  
        return $this->hasManyThrough(ProfilePhoto::class,Profile::class);


  


 $response=Category::with(['categoryPhotos'=>function($query)
            $query->where('profile_photos.photo_type',2);
            $query->orderBy('profile_photos.created_at','ASC');

          $query->groupBy('profile_photos.profile_id');

        ])->whereHas('categoryPhotos')->get();

如果不能通过 laravel 关系,那么 mysql 查询对我来说也很好。谢谢

【问题讨论】:

而且每个个人资料中只有一张照片(按 photo_type) 一组随机照片或一些确定的照片(例如,后者按创建日期)? by created_at desc and phototype=2 我尝试过使用 hasManyhrough 但按 created_at 降序不起作用 升序 - 有效吗? @Akina.asc 是默认行为,因此不会影响 我建议使用纯 SQL 来解决这个任务,然后看看它是否可以转换为 Laravel 语法,或者它必须作为原始执行。如果您接受这种方式,请在此级别添加表 DDL 和任务描述。 PS。 现在我需要按类别列出照片,并且每个个人资料中只需要按 photo_type 列出一张照片 - 看起来像“我需要类别列表,每个类别一张照片,前者有 created_at 和 @ 987654326@"。此外 - 如果在某些类别中没有带有 phototype=2(或根本没有)的照片怎么办? 【参考方案1】:

可能的解决方案(如果我正确理解任务)可能是

SELECT * 
FROM category ca
JOIN profile pr ON ca.id = pr.category_id
JOIN photos ph ON pr.id = ph.profile_id
JOIN ( SELECT ph1.profile_id, MAX(ph1.id) id
       FROM photos ph1
       JOIN ( SELECT profile_id, MAX(created_at) created_at 
              FROM photos 
              WHERE phototype=2
              GROUP BY profile_id ) sq1 ON ph1.profile_id = sq1.profile_id
                                       AND ph1.created_at = sq1.created_at 
       WHERE ph1.phototype=2
       GROUP BY ph1.profile_id ) sq2  ON ph.id = sq2.id

解释。

子查询 sq1 为 phototype=2 的照片的每个配置文件选择最后一个 created_at

子查询sq2 获取此结果并获得最大的id 照片,这些照片的个人资料和日期时间与sq1 中获得的照片匹配(如果超过1 张照片与条件匹配,则此子查询选择其中一张)。

FROM category ca
JOIN profile pr ON ca.id = pr.category_id
JOIN photos ph ON pr.id = ph.profile_id

收集所有可能的组合行 - 对于每个类别,它会获取所有相关配置文件和所有相关照片。然后我们加入我们的子查询,它过滤这个总列表,并为每个(类别、个人资料)对获取与我们条件匹配的照片的一行(或者,如果没有这样的照片,则没有选择任何对)。

以纯 SQL 形式对其进行测试(它是否给出正确的结果?从单独的 sq1 执行开始,检查,如果正确则执行 sq2 并再次检查,最后检查整个查询)。如果正确则尝试将其转换为 Laravel 形式。

【讨论】:

以上是关于Laravel hasmanythrough 或 mysql group by的主要内容,如果未能解决你的问题,请参考以下文章

Laravel hasManyThrough 等价物:通过另一个模型的 belongsTo 关系

Laravel 关系:hasManyThrough、belongsTo、belongsToMany

通过 Laravel 关系查询 HasManyThrough 检索相关记录

Laravel:如何平均嵌套 hasMany 关系(hasManyThrough)

Laravel 5 hasManyThrough 数据透视表

Laravel hasManyThrough 深入