【问题标题】:Eloquent One-to-Many OrderBy雄辩的一对多 OrderBy
【发布时间】:2014-03-08 02:36:09
【问题描述】:

我正在与 Eloquent 建立一对多关系。

我想通过使用他们最后发布的 DateTime (created_at) 来订购我的用户,但我不知道如何进行这项工作。

表用户:

 id | name 
 1  | John 
 2  | Doe
 3  | Foo
 4  | ...

表帖:

id | title  | body  | user_id | created_at 
1  | Title 1| Body1 | 1       | 2014-03-06 14:00:00
2  | Title 2| Body2 | 1       | 2014-03-04 14:00:00
3  | Title 3| Body3 | 2       | 2014-03-03 14:00:00
4  | Title 4| Body4 | 3       | 2014-03-05 14:00:00

所需的最终输出示例:

name | title   | created_at
John | Title 1 | 2014-03-06 14:00:00
Foo  | Title 4 | 2014-03-05 14:00:00
Doe  | Title 3 | 2014-03-03 14:00:00

我离得越近:

$users = User::with(['posts' => function($query){
     $query->orderBy('created_at', 'desc');
}])->get();

但是这段代码提取了每个用户的所有帖子,我只想要最后一个。

你能帮帮我吗?谢谢。

更新:我终于找到了我要找的东西:检索用户的最后一篇文章并按升序对用户进行排序(最后一篇文章的时间戳)。随时改进此查询!

$users = DB::table('posts')
    ->join('users', 'posts.user_id', '=', 'users.id')
    ->select(DB::raw('posts.id, posts.user_id, MAX(created_at) as created_at'))
    ->groupBy('posts.user_id')
    ->orderBy('created_at', 'asc')
    ->get();

【问题讨论】:

    标签: laravel laravel-4 eloquent


    【解决方案1】:

    你可以试试这个:

    $users = User::with(array('posts' => function($query){
        $query->orderBy('created_at', 'desc')->groupBy('user_id');
    }))->get();
    

    更新:你可以试试这个:

    $users = User::join('posts', 'users.id', '=', 'posts.user_id')
                 ->orderBy('posts.created_at', 'desc')
                 ->groupBy('posts.user_id')
                 ->select('users.*', 'posts.created_at as postTime')
                 ->get();
    

    我只从posts 表中选择了created_at,但您可以在select 中添加更多字段,例如:

    ->select('users.*', 'posts.created_at as postTime', 'posts.updated_at as postUpTime', 'posts.id as pid', 'posts.title')
    

    【讨论】:

    • 这是答案的一半。现在我只得到我的用户集合中的 last_post 数据。现在我想按他们的 last_post 时间戳对我的用户进行排序。我真的不知道怎么做。我的结构错了吗?
    • 检查更新的答案。如果使用$users->toArray(),结果会有所不同(将表合并为一个),但您可以使用$users->first()->posts->first() 之类的东西。
    • 非常感谢!正是我想要的!
    • 有没有一种简单的方法,通过这个查询,使用posts.created_at 重新排序,但以升序排列?换句话说,按升序获取用户的最后一篇文章。
    • 对不起!我不认为这是可能的,但如果可能的话我会发布。
    【解决方案2】:

    我相信你要么必须使用更复杂的usort(),要么你可以使用连接,但是使用这种方法,你也会失去 Eloquent 建立关系的方式。

    使用usort()...

    private function cmp($a, $b) 
    {
        if($a->posts->created_at == $b->posts->created_at) {
            return 0;
        }
        return (strtotime($a->posts->created_at) < strtotime($b->posts->created_at)) ? -1 : 1;
    }
    
    $users = User::with(array('posts' => function($query){
        $query->orderBy('created_at', 'desc')->groupBy('user_id')->first();
    }))->get();
    
    $users = usort($users, array($this, 'cmp'));
    

    或者,如果您更喜欢使用联接,我认为这应该适合您。

    $users = DB::table('posts')
        ->select(DB::raw('MAX(`posts`.`created_at`) AS `created_at`, `user_id`, `users`.*'))
        ->orderBy('posts.created_at', 'desc')
        ->groupBy('posts.user_id')
        ->join('users', 'users.id', '=', 'posts.user_id')
        ->get();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-12
      • 2016-07-20
      • 1970-01-01
      • 2012-10-08
      • 2018-10-27
      • 2014-10-08
      • 2014-05-23
      • 2020-09-20
      相关资源
      最近更新 更多