【问题标题】:Query Top 5 categories with the most content, return 5 content from each category and join associaled user name with content with laravel查询内容最多的前 5 个类别,每个类别返回 5 个内容,并使用 laravel 将 associaled 用户名与内容连接起来
【发布时间】:2019-02-20 14:36:33
【问题描述】:

我对 laravel 很陌生,并且很难使用它...

我有 3 张桌子

类别:

id,
name,
...;

视频:

id,
category_id,
user_id,
..;

用户:

id 

在类别模型中,我与视频创建了一个 hasmany 关系:

public function video()
{
    return $this->hasMany('App\Video')->where('isLive', 1);
}

在视频模型中,belongsTo 与类别的关系

public function category()
{
    return $this->belongsTo('App\Category');
}

在类别控制器中,我通过运行以下查询获取数据

 public function index()
{
    $data = \App\Category::where('is_active', 1)
                ->with('video')
                ->paginate(15);
}

我的主要问题是如何将每个视频的用户名与结果结合起来

小问题是获得最多视频的前 5 个类别

【问题讨论】:

  • 您是否为视频模型创建了与用户的关系?
  • 是的,但我不知道如何链接查询以获取每个视频的用户名
  • 请编辑并将其添加到您的问题中以获得更好的答案

标签: php mysql laravel eloquent


【解决方案1】:

要获得视频最多的前 5 个类别:

$top5Cat = Category::withCount('video')->orderBy('video_count', 'desc')->limit(5)->get();

然后您可以添加急切加载以获取其中的 5 个视频:

$top5CatWithVideos = Category::withCount('video')->with(['video' => function($q){
    return $q->take(5);
}])->orderBy('video_count', 'desc')->limit(5)->get();

建议将关系函数从 video 更新为 videos 作为其 hasMany

现在添加每个视频的用户:

$top5CatWithVideos = Category::withCount('video')->with(['video' => function($q){
        return $q->take(5);
}, 'video.user'])->->orderBy('video_count', 'desc')->limit(5)->get();

【讨论】:

  • 谢谢,问题只解决了一半我只需要一种方法来包含每个视频的每个用户的用户名。
  • 我在急切加载视频时也添加了用户关系。请检查更新的答案。
【解决方案2】:

不是我写的最漂亮的查询,但是你可以用 SQL 做到,使用 IN(subquery(subquery())) 的原因是能够使用 LIMIT

SELECT
    b.*,
    u.username
FROM
    (
        (SELECT video.* FROM video
        WHERE video.category_id IN(
                SELECT a.category_id
                FROM
                    (
                        SELECT category_id FROM video GROUP BY category_id ORDER BY count(*) DESC LIMIT 1
                    ) as a
            )
        LIMIT 5)
        UNION (SELECT video.* FROM video 
        WHERE video.category_id IN(
                SELECT a.category_id
                FROM
                    (
                        SELECT category_id FROM video GROUP BY category_id ORDER BY count(*) DESC LIMIT 1,1
                    ) as a
            )
        LIMIT 5)
        UNION (SELECT video.* FROM video 
        WHERE video.category_id IN(
                SELECT a.category_id
                FROM
                    (
                        SELECT category_id FROM video GROUP BY category_id ORDER BY count(*) DESC LIMIT 2,1
                    ) as a
            )
        LIMIT 5)
        UNION (SELECT video.* FROM video 
        WHERE video.category_id IN(
                SELECT a.category_id
                FROM
                    (
                        SELECT category_id FROM video GROUP BY category_id ORDER BY count(*) DESC LIMIT 3,1
                    ) as a
            )
        LIMIT 5)
        UNION (SELECT video.* FROM video 
        WHERE video.category_id IN(
                SELECT a.category_id
                FROM
                    (
                        SELECT category_id FROM video GROUP BY category_id ORDER BY count(*) DESC LIMIT 4,1
                    ) as a
            )
        LIMIT 5)
    ) as b
JOIN user u ON
    u.id = b.user_id

在那之后我认为你在 laravel 中做了这样的事情:

$videos = DB::select($aboveQuery);

【讨论】:

    猜你喜欢
    • 2011-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-03
    • 2017-10-20
    相关资源
    最近更新 更多