0

私は小さなフォーラムを作成しています。

クエリを実行しようとするとSElECT... JOIN...、個々の投稿に関する情報と最後の返信 (ある場合) が取得されます。すべてを難しい方法で行いたいという私の願望の一環として、これには 5 つの表が含まれます (この問題に関連する列のみが記載されています)。

コメント情報参照 ID | 参照タイプ | 著者ID | 作成
投稿 ID | 題名
postitInfo リファレンスPostitID | 作成 | 著者ID
ユーザー ID | ユーザー名 | 許可
userInfo リファレンスUserID | 題名

そこで、このクエリSELECT... JOIN...クエリを実行して、最新のトピックとその最新の返信を取得します。

SELECT DISTINCT
    t1.id, t1.title, t2.create, t2.lastEdit, t2.authorID, t3.username, 
    t4.title AS userTitle, t3.permission, t5.create AS commentCreate, 
    t5.authorID AS commentAuthor, t6.username AS commentUsername, 
    t6.permission AS commentPermission
FROM rantPostit AS t1
LEFT JOIN (rantPostitInfo AS t2) 
    ON ( t1.id = t2.referencePostitID)
LEFT OUTER JOIN (rantUser as t3, rantUserInfo as t4) 
    ON (t2.authorId = t3.id AND t4.referenceUserId = t2.authorId)
LEFT OUTER JOIN (rantCommentInfo as t5, rantUser as t6) 
    ON (t5.referenceType = 8 AND t5.referenceID = t1.id AND t6.id = t5.authorID)
ORDER BY t2.create DESC, t5.create DESC

これで、トピックの投稿が返されます。2つ持っているとしましょう。両方とも正常に返されます。最初の返信に対して 8 つの返信があるとします。9 つのエントリが返されます (トピック + 返信に 1 つずつ、返信のない個々のエントリ)。だから、私の問題はこれだと思います.最後のLEFT OUTER JOIN節の返品の数を最新のものだけに制限するために何をすべきかわかりません。

(はい、ORDER BY...最初に投稿の作成日、次にコメントの作成日で順序付けされるため、句がめちゃくちゃになっていることに気付きました。はい、2つのフィールドをpostitInfo、lastCommentCreate、およびlastCommentCreateID を作成し、返信があるたびに更新するようにしますが、難しい方法が好きです。)

それで、私は何を間違っていますか?

それとも、私が薪小屋を回ってハンマーで叩かなければならないほど馬鹿げた問題なのでしょうか?

4

2 に答える 2

1

postpostInfo、およびuserとテーブルの間の分割は、userInfo難読化すること以外は何もしていないように見えます。解決策をよりよく理解するために、物事を本質にまで煮詰めてみましょう: テーブルPosts( 主キーid、作成日date、およびその他のフィールドを持つ) とテーブルComments(主キー、参照idする外部キー、一意の作成日などを持つ)田畑); すべての投稿を表示し、それぞれに最新のコメントがある場合はそれを表示します (取得したテーブル行の主キーと他のフィールドはもちろん、コンテキストで使用できます)。refIdPostsdateidSELECTより多くの情報を取得して表示することはできますが、それによってコア構造が変わるわけではなく、コア構造まで単純化することで解決策を示すことができます)。コメントの作成日は一意であると想定しています。そうでない場合、「最新のコメント」があいまいになる可能性があります (もちろん、そのあいまいさは、特定の投稿に対する「最新のコメント」のセットの 1 つの項目を選択することで、他の方法で任意に切り詰めることができます)。 )。

したがって、ここに1つのアプローチがあります:

SELECT Posts.id, Comments.id FROM Posts
LEFT OUTER JOIN Comments on (Posts.id = Comments.refId)
WHERE Comments.create IS NULL OR (
      Comments.create = (SELECT create FROM Comments
                         WHERE refID = Posts.id
                         ORDER BY create DESC
                         LIMIT 1)
) /* add ORDER BY &c to taste;-) */

アイデア: 各投稿に対して、「null コメント」(コメントがない場合)、または投稿を参照しているコメントの中で作成日が最も高いコメントが必要です。ここでは、インナーSELECTが「最高の」作成日を見つけます。したがって、同じ精神で、内側の選択SELECT MAX(create) FROM Comments WHERE refID = Posts.idがおそらく好ましいかもしれません(より短く、より直接的で、おそらくより高速です)。

于 2009-05-23T22:07:08.293 に答える
0

複数の行を返すことができるのは、最後の LEFT JOIN だけのようです。そうであれば、LIMIT 5 を使用して最後の 5 つのコメントを取得できます。

 ORDER BY t5.create DESC
 LIMIT 5

そうでない場合、非常に簡単な解決策は、別のクエリでコメントを取得することです。

SELECT *
FROM rantCommentInfo t5
    ON t5.referenceType = 8 
    AND t5.referenceid = t1.id
LEFT OUTER JOIN rantUser t6
    ON t6.id = t5.authorID
ORDER BY CommentCreate
WHERE t5.referenceid = YourT1Id
LIMIT 5

MySQL がサポートしていない ROW_NUMBER を使用せずに、1 つのクエリでそれを行う方法は考えられません。

于 2009-05-23T21:42:39.620 に答える