# [MySQL] Left Join über mehrere Tabellen, mit mehrfacher Sortierung



## MrAnderson (21. Mai 2014)

Hallo,

aktuell arbeite ich an einem Forum, für das ich nun MySQL Abfragen erstellen muss.

Für die Forum Übersicht möchte ich folgende Daten aus der Datenbank laden.

Titel des Forums
Beschreibung des Forums

Letztes Thema (Welches den neusten Post beinhaltet.)
Letzter Post von (Den Benutzernamen des Mitgliedes, welches den neuesten Post verfasst hat.)
Timestamp des letzten Posts

Anzahl der Beiträge in dem Forum
Anzahl der Themen in dem Forum
Mein Problem:
Die aktuelle Abfrage gibt mir zwar alle Foren und die passenden Details dazu aus, jedoch schaffe ich es nicht die Tabellen (forum_post) absteigend zu sortieren.  Eine zusätzliche "ORDER BY" Anweisung wird einfach ignoriert, sobald ich "GROUP BY"  der Abfrage hinzufüge.

Gibt es eine Möglichkeit die Tabellen mit Joins zu sortieren oder muss ich auf Subselects zurückgreifen?

Meine Abfrage:

```
SELECT
  forum_board.boardID AS board_id,
  forum_board.description AS board_description,
  forum_board.title AS board_title,
  forum_thread.title AS thread_title,
  forum_post.postTimestp AS post_timestp,
  usersys_user.username AS post_username,
  COUNT(forum_thread.threadID) AS num_threads,
  COUNT(forum_post.postID) AS num_posts,
  forum_post.postID AS LAST_POST_ID_FOR_DEBUG
FROM forum_board
  LEFT OUTER JOIN forum_thread
    ON forum_board.boardID = forum_thread.boardID
  LEFT OUTER JOIN forum_post
    ON forum_thread.threadID = forum_post.threadID
  LEFT OUTER JOIN usersys_user
    ON forum_post.userID = usersys_user.userID
WHERE forum_board.isSubBoardOf NOT LIKE 0
GROUP BY forum_board.boardID
ORDER BY board_id
```


Edit: Kann man den Titel hier nicht mehr nachträglich ändern? Hab vergessen Mysql im Titel mit anzugeben.


----------



## Yaslaw (21. Mai 2014)

Du hast da ganz andere Probleme.
Du solltest UNBEDINGT alle Felder aus dem SELECT-Teil, die nicht mit einer Gruppierungsfunktion (SUM, COUNT etc) versehen sind, in den GROUP-Teil nehmen.
MySQL ist die einzige DBMS die ich kenne, die ein so unsauberen Code zulässt. Gewöhne es dir gar nicht erst an. Grad in deinem Beispiel sieht man das Problem

So wir du es jetzt hast, wird num_threads und num_posts immer 1 sein. Eine Gruppierung macht so gar keinen Sinn. Die Granularität wird auf user*thread sein.

Die Sortierung müsste eigentlich gehen. Kann mit den fehlenden Feldern im GROUP BY zusammenhängen. Wennd u auf nummer sicher gehen willst, mach daraus ein Subquery und sortiere dann das Endresultat

Etwa so würde es sauber aussehen. Ich musste ein par Annahmen treffen.

```
SELECT
  forum_board.boardID AS board_id,
  forum_board.description AS board_description,
  forum_board.title AS board_title,
  forum_thread.title AS thread_title,
  -- Ich nehm heir nur die aktuellesten Timestamp
  MAX(forum_post.postTimestp) AS post_timestp,
  MAX(usersys_user.username) AS post_username,
  COUNT(forum_thread.threadID) AS num_threads,
  COUNT(forum_post.postID) AS num_posts,
  -- Wenn du die Letzte haben willst, dann nimm das auch
  MAX(forum_post.postID) AS LAST_POST_ID_FOR_DEBUG
FROM forum_board
  LEFT OUTER JOIN forum_thread
  ON forum_board.boardID = forum_thread.boardID
  LEFT OUTER JOIN forum_post
  ON forum_thread.threadID = forum_post.threadID
  LEFT OUTER JOIN usersys_user
  ON forum_post.userID = usersys_user.userID
WHERE forum_board.isSubBoardOf NOT LIKE 0
GROUP BY
  forum_board.boardID,
  forum_board.description,
  forum_board.title,
  forum_thread.title
ORDER BY board_id
```

Oder dann eben mit dem SELECT über alles das dann sortiert wird

```
SELECT
  t.*
FROM
  (
  SELECT
  forum_board.boardID AS board_id,
  forum_board.description AS board_description,
  forum_board.title AS board_title,
  forum_thread.title AS thread_title,
  -- Ich nehm heir nur die aktuellesten Timestamp
  MAX(forum_post.postTimestp) AS post_timestp,
  MAX(usersys_user.username) AS post_username,
  COUNT(forum_thread.threadID) AS num_threads,
  COUNT(forum_post.postID) AS num_posts,
  -- Wenn du die Letzte haben willst, dann nimm das auch
  MAX(forum_post.postID) AS LAST_POST_ID_FOR_DEBUG
  FROM forum_board
  LEFT OUTER JOIN forum_thread
  ON forum_board.boardID = forum_thread.boardID
  LEFT OUTER JOIN forum_post
  ON forum_thread.threadID = forum_post.threadID
  LEFT OUTER JOIN usersys_user
  ON forum_post.userID = usersys_user.userID
  WHERE forum_board.isSubBoardOf NOT LIKE 0
  GROUP BY
  forum_board.boardID,
  forum_board.description,
  forum_board.title,
  forum_thread.title
  ) t
ORDER BY
  t.board_id
```


----------

