Mysql
 sql >> Base de données >  >> RDS >> Mysql

SQL :sélectionnez le dernier fil de discussion et le dernier message, regroupés par forum, classés par le dernier message

Étant donné que MySQL ne prend pas en charge les fonctions de fenêtre, je ne pense pas qu'il soit possible de le faire sans sous-requête :

SELECT  f.id AS forum_id,
    f.name AS forum_name,
    t.id AS thread_id,
    t.topic AS thread_topic,
    t.ts AS thread_timestamp,
    p.id AS post_id,
    p.content AS post_content,
    p.ts AS post_timestamp

FROM   forums f
JOIN (SELECT t2.forum_id, max(p2.ts) as ts
      FROM posts p2
      JOIN threads t2 ON p2.thread_id = t2.id
      GROUP BY t2.forum_id) max_p ON f.id = max_p.forum_id
JOIN   posts p ON max_p.ts = p.ts
JOIN   threads t ON f.id = t.forum_id AND p.thread_id = t.id
ORDER BY p.ts

Naturellement, la mise en cache des derniers résultats vous permettrait de le faire sans la pénalité de performances liée à l'appel de MAX(), mais avec les bons index, cela ne devrait pas poser de problème...

MISE À JOUR

La façon la plus concise d'inclure les fils de discussion sans messages et les forums sans fils serait d'utiliser des LEFT JOIN au lieu d'un INNER JOIN :

SELECT  f.id AS forum_id,
    f.name AS forum_name,
    t.id AS thread_id,
    t.topic AS thread_topic,
    t.ts AS thread_timestamp,
    p.id AS post_id,
    p.content AS post_content,
    p.ts AS post_timestamp

FROM   forums f
LEFT JOIN (SELECT t2.forum_id, max(COALESCE(p2.ts, t2.ts)) as ts, COUNT(p2.ts) as post_count
      FROM threads t2 
      LEFT JOIN posts p2 ON p2.thread_id = t2.id
      GROUP BY t2.forum_id) max_p ON f.id = max_p.forum_id
LEFT JOIN   posts p ON max_p.ts = p.ts
LEFT JOIN   threads t ON f.id = t.forum_id AND (max_p.post_count = 0 OR p.thread_id = t.id)
ORDER BY p.ts