【发布时间】:2013-05-18 18:59:20
【问题描述】:
我为正在创建的论坛应用程序创建了三个表:
-
boards- 代表帖子的集合,is_deletedboolean -
posts- 表示一些文本以及 cmets 的集合 -
comments- 代表一些文字
我的目标是显示一定数量的未标记为已删除的板上的所有帖子,按对帖子的最后评论排序(然后是创建帖子的时间)。我必须这样做的当前查询是:
SELECT
posts.*,
(SELECT created_date
FROM comments
WHERE comments.post_id = posts.id
ORDER BY comments.created_date DESC
LIMIT 1) as last_comment
FROM posts
JOIN boards ON boards.id = posts.board_id
WHERE boards.is_deleted = 0
ORDER BY
last_comment DESC,
posts.created_date DESC
LIMIT 4
OFFSET 0
效果很好,但我实际上并不需要last_comment,除非我使用它来订购结果,所以感觉就像我正在运行一个额外的 SELECT 没有什么理由。有没有更好的方法来做到这一点?
编辑 2013-05-18:
再玩弄一下,我相信我有一个不依赖嵌套 SELECT 语句的查询:
SELECT
posts.*
FROM posts
JOIN boards
ON boards.id = posts.board_id
LEFT OUTER JOIN comments
ON posts.id = comments.post_id
WHERE
boards.is_deleted = 0
GROUP BY
posts.id
ORDER BY
comments.created_date DESC,
posts.created_date DESC
LIMIT 4
OFFSET 0
【问题讨论】:
-
1.根据您运行的数据库,您可以为最后一条评论提供具体视图,这将使查询更快,但更新会更重 2. 您可以使数据非规范化并将最后一条评论存储在 post 表中,以及 3. 如果您担心性能那么您可能应该将
SELECT移动到JOIN(除非db 自动执行此操作)并使用键来提高查询效率(外键等)。只要它可读并且数据库优化器可以处理它,我就不会太关心查询本身。 -
谢谢,Maciej!从发布到现在,我一直在搞乱它,我只是用一个更新的查询编辑了我的原始帖子,我相信它可能会更好。它将嵌套的
SELECT转换为LEFT OUTER JOIN以及GROUP BY。