0

作成中のフォーラム アプリケーション用に 3 つのテーブルがあります。

  • 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 ステートメントのみを作成するようにします。その 2 番目の select ステートメントなしでそれを行う場合、データが保存された時点でこの情報を posts-table に保存する場合にのみそれを行うことができます。次に、たとえば「last_comment」という名前の列をposts-tableに追加し、そのフィールドにコメントの作成時間を配置する必要がありますか。その場合、投稿テーブルのフィールド「last_comment」の順序で 2 番目のステートメントを置き換えることができます。ただし、将来変更される可能性がある機能要件のために、テーブルを変更します。そうすることはお勧めしません。各テーブルまたはビューは異なるオブジェクトであり、SQL は絶えず変化する機能要件を処理します。

于 2013-05-18T19:26:20.877 に答える