0

我为正在创建的论坛应用程序创建了三个表:

  • boards- 表示帖子的集合,is_deleted布尔值
  • posts- 代表一些文本以及评论的集合
  • 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
4

1 回答 1

0

那时没有比通过另一个 select 语句更好的方法来做到这一点。

您可以将 select 语句放在不同的位置,例如:

select p.*, com.created_date from posts p, comments com, boards b where b.id = p.board_id
and b.is_deleted = 0 and com.id in (select c.id from comments c where c.post_id = p.id 
order by c.created_date desc limit 1) order by com.created_date desc, p.created_date desc 
limit 4 offset 0;

查询规划器旨在优化 where 子句,因此如果可能的话,我将尝试在 where 子句中只创建 select 语句。如果您在没有第二条 select 语句的情况下执行此操作,那么只有在保存数据时将此信息存储在帖子表中时您才能执行此操作。然后您是否必须在帖子表中添加一列,例如名称“last_comment”并将评论的创建时间放在该字段中。在这种情况下,您可以通过帖子表中字段“last_comment”的排序来替换第二条语句。但是,由于将来可能会更改的功能要求,您会更改表。我不建议你这样做。每个表或视图都是一个不同的对象,SQL 负责处理不断变化的功能需求。

于 2013-05-18T19:26:20.877 回答