我有两个模型/表:用户和帖子。用户可以有很多帖子,每个帖子属于一个用户。
我尝试根据创建最新帖子的时间以升序返回用户列表。
例如
users:
id | name |
--------------------
1 | user 1 |
2 | user 2 |
3 | user 3 |
posts:
id | user_id | created_at |
---------------------------------------------
1 | 1 | 2018-02-19 08:00 |
2 | 2 | 2018-02-19 09:00 |
3 | 3 | 2018-02-19 10:00 |
4 | 1 | 2018-02-19 11:00 |
5 | 1 | 2018-02-19 12:00 |
6 | 2 | 2018-02-19 13:00 |
我希望能够返回以下结果
[
{
id: 3,
name: "user 3"
},
{
id: 1,
name: "user 1"
},
{
id: 2,
name: "user 2"
}
]
由于用户3最近一次创建了他们最近发布的帖子,其次是用户1,然后是用户2.
到目前为止,我已经尝试了这一点,但它为用户返回了重复的结果:
return $this->builder
->join('posts', function ($join) {
$join->on('users.id', '=', 'posts.user_id')
->orderBy('posts.created_at', 'desc')
->limit(1);
})
->orderBy('posts.created_at', 'asc')
->get();
我也试过这个没有返回任何重复结果,但排序错误:
return $this->builder
->join('posts', 'users.id', '=', 'posts.user_id')
->groupBy('users.id')
->take(1)
->orderBy('posts.created_at', 'asc')
->get();
我觉得这是我之后的两种组合,但我无法解决这个问题。非常感谢任何帮助,非常感谢。我使用的是Laravel 5.4
答案 0 :(得分:1)
这是一个原始的MySQL查询应该可以解决这个问题:
SELECT
t1.id, t1.name
FROM users t1
LEFT JOIN
(
SELECT user_id, MAX(created_at) AS created_at
FROM posts
GROUP BY user_id
) t2
ON t1.id = t2.user_id
ORDER BY
t2.created_at;
以下是我对相应的Laravel查询的尝试:
DB::table('users')
->select('id', 'name')
->join(DB::raw('(SELECT user_id, MAX(created_at) AS created_at
FROM posts GROUP BY user_id) t'),
function($join)
{
$join->on('users.id', '=', 't.user_id');
})
->orderBy('t.created_at', 'ASC')
->get();
答案 1 :(得分:0)
我知道这不是你想要的确切事情,但你可以这样做
Post::with('user')->orderBy('created_at', 'DESC')->distinct()->get(['user_id']);
它会给你这个
array:3 [▼
0 => array:2 [▼
"user_id" => 1
"user" => array:13 [▶]
]
1 => array:2 [▼
"user_id" => 2
"user" => array:13 [▶]
]
2 => array:2 [▼
"user_id" => 3
"user" => array:13 [▶]
]
]