我这里有4个单独的选择子查询,只选择我需要的1列 - 但我知道这是低效的。
如何通过连接实现同样的目标?我已尝试使用group by连接子集中的子查询,但遗憾的是无法使其工作。
SELECT [columns needed],
(SELECT posts.created_at FROM posts WHERE posts.thread_id = threads.id ORDER BY posts.created_at DESC LIMIT 1) as lastpost_created_at,
(SELECT users.username FROM posts INNER JOIN users on posts.user_id = users.id WHERE posts.thread_id = threads.id ORDER BY posts.created_at DESC LIMIT 1) as lastpost_username,
(SELECT users.avatar FROM posts INNER JOIN users on posts.user_id = users.id WHERE posts.thread_id = threads.id ORDER BY posts.created_at DESC LIMIT 1) as lastpost_avatar,
(SELECT COUNT(*) FROM posts WHERE posts.thread_id = threads.id) as replies
FROM threads
INNER JOIN posts ON threads.post_id = posts.id
INNER JOIN users ON posts.user_id = users.id
ORDER BY lastpost_created_at DESC
答案 0 :(得分:1)
我不确定我是否正确解释,但似乎你想得到:
我已将SQLfiddle放在一起,我认为这些提供所有这些,请在下面查询:
select threads.id,
lastpost_created_at.lastpost,
posts.user_id,
/* posts.other_fields, */
users.avatar,
/* users.other_fields, */
post_counts.replies
from threads
left join
(
/* first we aggregate the posts by thread_id
to get the most recent created timestamp. */
/* Note that this assumes unique timestamp per post / thread_id */
select max( posts.created_at ) as lastpost,
thread_id
from posts
group by thread_id
) as lastpost_created_at
on threads.id = lastpost_created_at.thread_id
/* Now we join on to the posts table to get the associated user id */
/* (and any other fields you want from posts)*/
left join
posts
on threads.id = posts.thread_id
and posts.created_at = lastpost_created_at.lastpost
/* Then grab the user avatar etc */
left join
users
on posts.user_id = users.id
/* and finally get the total number of replies per thread */
left join
(
select thread_id,
count(*) as replies
from posts
group by thread_id
) as post_counts
on threads.id = post_counts.thread_id
一个注意事项:如果单个帖子的两个帖子具有完全相同的created_at
时间戳,则会导致两个帖子都出现重复的行。
修改强>
我把一个只在一个重复时间戳的情况下返回一个结果的查询放在一起:
select threads.id,
most_recent_post.created_at,
most_recent_post.user_id,
users.avatar,
post_counts.replies
from threads
left join
(
/* Get the most recent post per thread, ordered by created at and ID */
select di.id, di.user_id, di.created_at, di.thread_id
from (
select thread_id, max(created_at) AS created_at
from posts d
group by thread_id
) as dd
inner join
posts as di
on di.id = (
select id
from posts ds
where ds.thread_id = dd.thread_id
and ds.created_at = dd.created_at
order by id desc
limit 1
)
) as most_recent_post
on threads.id = most_recent_post.thread_id
/* Then grab the user avatar etc */
left join
users
on most_recent_post.user_id = users.id
/* and finally get the total number of replies per thread */
left join
(
select thread_id,
count(*) as replies
from posts
group by thread_id
) as post_counts
on threads.id = post_counts.thread_id