Abfrage liefert falsches Ergebnis (ORDER/GROUP Problem)

fanste

Erfahrenes Mitglied
Hi,

ich habe hier einen MySQL Query, der mir aus 4 Tabellen zusammenhängende Daten hohlt. Diese sind für ein Forum. Um genauer zu sein, für die Themenanzeige in einem Forum. Alles klappt soweit wunderbar, nur eines nicht und das ist die Sortierung nach der Zeit. GROUP BY greift vor ORDER BY und kann daher die Beiträge nicht mehr innerhalb eines Themas sortieren. Statt den letzten Beitrag eines Themas, erhalte ich immer den Ersten. Erst sortieren und dann zusammenfassen geht leider nicht :(

Hier mal der Query. Vielleicht kann mir den jemand so anpassen, dass es funktioniert. Eigentlich wollte ich alles schön kompakt in einem Query haben. Wenn es aber nicht vermeidbar ist, einen zweiten/dritten benützen zu müssen, dann sei es so.

SQL:
SELECT
      `bt`.`id` as t_id,
      `bt`.`starter_name` as t_sn,
      `bt`.`starter_id` as t_sid,
      `bt`.`name` as t_t,
      `bt`.`klicks` as t_v,
      `bt`.`path` as t_p,
      `bp`.`author_name` as p_an,
      `bp`.`author_id` as p_aid,
      `bp`.`time` as p_t,
      #`bp`.`title` as p_n,
      `bc`.`id` as bc_id,
      `bc`.`name` as bc_n,
      `bb`.`name` as bb_n,
      COUNT(`bp`.`id`) as p_count #das muss man noch ändern... später
FROM
      `board_topics` as bt,
      `board_posts` as bp,
      `board_columns` as bc,
      `board_boards` as bb
WHERE
      `bc`.`id` = '".$id."'
      AND `bb`.`id` = `bc`.`parent`
      AND `bt`.`path` = CONCAT(`bc`.`parent`, '-', `bc`.`id`)
      AND `bp`.`path` = CONCAT(`bt`.`path`, '-', `bt`.`id`)
GROUP BY
      `bt`.`id`
ORDER BY
      `bp`.`time` DESC
LIMIT $start, $topics_per_page

Danke schonmal für eure Bemühungen

Kleine anmerkung: Es steht mit MySQL5 zur Verfügung, wenn das hilft
 
Zuletzt bearbeitet:
Hmm, spontan habe ich das hier gefunden:
http://dev.mysql.com/doc/refman/5.0/en/select.html hat gesagt.:
If you want to use ORDER BY before GROUP BY, the only way I've found to achieve it is with a subquery.

For example, if you want to get a list of users from a table UserActions sorted according to the most recent action (based on a field called Time) the query would be:

SELECT * FROM (SELECT * FROM UserActions ORDER BY Time DESC) AS Actions GROUP BY UserID ORDER BY Time DESC;

Without the subquery, the group is performed first, and so the first record that appears in the database (which is not necessarily in the order you want) will be used to determine the sort order. This caused me huge problems as my data was in a jumbled order within the table.

--Edit--
This same result can be achieved with the use of MAX(Time), so the query would be:

SELECT *, MAX(Time) AS LatestAction GROUP BY UserID ORDER BY LatestAction DESC;

As far as I can see, the subquery model still holds up if you need more complex sorting before performing the GROUP.

Alternative Möglichkeit: Mit PHP sortieren?
 
Von Subquery hab ich auch schon gelesen, aber ich habe keine Ahnung, wie ich das in meinem Fall anwenden muss.

Auch auf die MAX() Idee bin ich gekommen (angwandt auf `bp`.`time`). Schön dachte ich mir, funktioniert... denkste: Die Zeit hat gestimmt, aber es wurde immer noch der user vom ersten Post ausgewählt und nicht der, der in der Spalte steht, wo auch die MAX Zeit herkommt ;)
 
Sorry für den Doppelpost, aber...
Problem gelöst ;) Wie so oft erst dann, wenn man schon nach Hilfe geschriehen hat. geholfen hat mir die Seite "http://mysql-faq.sourceforge.net/anwendung7.html" die mir auf einmal Google ausgespuckt hat

Mein Query sieht nun so aus. Wer was dagegen einzuwenden hat, tut das bitte und schreibt auch gleich ne schönere/bessere Lösung dazu :)

SQL:
SELECT
     `bt`.`id` as t_id,
     `bt`.`starter_name` as t_sn,
     `bt`.`starter_id` as t_sid,
     `bt`.`name` as t_t,
     `bt`.`klicks` as t_v,
     `bt`.`path` as t_p,
     `bp`.`author_name` as p_an,
     `bp`.`author_id` as p_aid,
     `bp`.`time` as p_t,
     #`bp`.`title` as p_n,
     `bc`.`id` as bc_id,
     `bc`.`name` as bc_n,
     `bb`.`name` as bb_n
     #COUNT(`bp`.`id`) as p_count #das muss man noch ändern... später
FROM
     `board_topics` as bt,
     `board_posts` as bp,
     `board_columns` as bc,
     `board_boards` as bb
LEFT JOIN
     `board_posts` as bp2
ON
     (
     	`bp2`.`path` = CONCAT(`bt`.`path`, '-', `bt`.`id`)
     	AND `bp`.`time` < `bp2`.`time`
     )
WHERE
     `bc`.`id` = '4'
     AND `bb`.`id` = `bc`.`parent`
     AND `bt`.`path` = CONCAT(`bc`.`parent`, '-', `bc`.`id`)
     AND `bp`.`path` = CONCAT(`bt`.`path`, '-', `bt`.`id`)
     AND `bp2`.`time` IS NULL
ORDER BY
     `p_t` DESC
 
Zuletzt bearbeitet:
Verwende doch mal einen richtigen JOIN, das hilft bei der Lesbarkeit & Übersichtlichbarkeit. Diese Art von Queries sollte verboten werden :D
 
Verwende doch mal einen richtigen JOIN, das hilft bei der Lesbarkeit & Übersichtlichbarkeit. Diese Art von Queries sollte verboten werden :D

Ja.. und wenn ich mich nicht irre sind on gegenüber where verknüpfungen einiges performer. (Ich weiss es deshalb nicht, weill ich schon immer on benutzt hab ^^)
 
Und was versteht ihr unter einem "richitigen" JOIN? Wenn ich wüsste, wie man das ganze möglichst schnell machen könnte, würde ich ja nicht hier fragen -.-

Also, macht mal ein Beispiel anhand meines Querys ;)
 

Neue Beiträge

Zurück