Zur Navigation

ORDER BY ...

1 tomaschko

Hi,

in meinem programmiertem Forum ist mir ein Fehler aufgefallen, den ich nicht behoben kriege. In der Threadübersicht werden die threads nicht nach dem jeweils neuesten posts geordnet, aber ich weiss nicht wie ich es realisieren soll. einfach nach date ordnen geht ja nicht, weil es dann das datum der erstellung nimmt, statt des letzten posts.

 
//anzeige der themen des forums   
    foren_breadcrumb();
    $result = mysql_query("SELECT * FROM threads WHERE fid=$fid GROUP BY tid");


    while($row = mysql_fetch_object($result)){
    $id = $row->id;
    $thread_id = $row ->tid;
    $topic = $row->topic;
    $description = $row->description;
    $user = $row->user;
    $date = $row->date;
 
    $lresult = mysql_query("SELECT id, topic, user, date FROM threads WHERE fid=$fid AND tid=$thread_id ORDER BY date DESC LIMIT 1");
     while($row = mysql_fetch_object($lresult)){
     $lid = $row->id;
     $ltopic = $row->topic;
     $luser = $row->user;
     $ldate = $row->date;
     //ergebniszähler
   $num_result = mysql_query("SELECT * FROM threads WHERE fid=$fid AND tid=$thread_id");
    $posts = mysql_num_rows($num_result);

    $seiten=ceil($posts/$anzeige);

   //ausgabe    


    echo '<table class="threads" border="0"><tr>';
    echo '<td class="thread_topic"><b><a href="discuss.php?fid='.$fid.'&tid='.$thread_id.'&page=1">'.$topic.'</a></b><br>'.$description.'</td>';
    echo '<td class="thread_user">eröffnet von: '.$user.'</td>';
    echo '<td class="thread_posts">Posts: '.$posts.'</td>';
    echo '<td class="thread_date">am: '.$date.'</td>';
    echo '<td class="thread_lpost">'.($lid ? ' <a href="discuss.php?fid='.$fid.'&tid='.$thread_id.'&page='.$seiten.'&pid='.$lid.'#pid'.$lid.'">letzter Post</a>, <b>'.$luser.'</b><br><small>'.$ldate.'</small></td></tr>'; 
    echo '</table>'; 
    
    }
    }echo ' <a href="discuss_new.php?fid='.$fid.'">neues thema</a>';
    }
    else {
    //anzeige der beitraege    

Ist er echt?

17.01.2007 10:47

2 Jörg

Hallo tomaschko,

grundsätzlich sehe ich zwei Möglichkeiten:

1. du machst eine JOIN Abfrage über die Tabellen, die die Threads und die Posts enthalten, gruppierst die Einträge nach den Thread-IDs und sortierst nach dem maximalen Timestampo der Posts.

2. du legst in der thread Tabelle noch eine Spalte an für einen Timestamp "lastpost", nach welcher du dann sortieren kannst. In dem Fall musst bei jedem Post auch die threads Tabelle aktualisieren

17.01.2007 11:17

3 tomaschko


Zitat von Jörg
Hallo tomaschko,

grundsätzlich sehe ich zwei Möglichkeiten:

1. du machst eine JOIN Abfrage über die Tabellen, die die Threads und die Posts enthalten, gruppierst die Einträge nach den Thread-IDs und sortierst nach dem maximalen Timestampo der Posts.

2. du legst in der thread Tabelle noch eine Spalte an für einen Timestamp "lastpost", nach welcher du dann sortieren kannst. In dem Fall musst bei jedem Post auch die threads Tabelle aktualisieren

posts stehen in der threadtabelle

Struktur

 `id` int(10) unsigned NOT NULL auto_increment,
  `fid` int(11) NOT NULL default '0',
  `topic` varchar(255) NOT NULL default '',
  `description` text NOT NULL,
  `tid` int(1) NOT NULL default '0',
  `user` varchar(255) NOT NULL default '',
  `email` varchar(255) NOT NULL default '',
  `website` varchar(255) NOT NULL default '',
  `date` datetime NOT NULL default '0000-00-00 00:00:00',
  `content` longtext NOT NULL,
  PRIMARY KEY  (`id`)

Das ist auch der grund warum es mich wundert das er nur nach der erstellung sortiert. Evt. wegen der group by tid anweisung?



Ist er echt?

17.01.2007 11:34

4 Jörg

posts stehen in der threadtabelle

Hm, dann ist der Name threads etwas missverständlich.

Du könntest vielleicht nach MAX(date) sortieren - ich weiß allerdings nicht, ob das Format '0000-00-00 00:00:00' zum Sortieren überhaupt geeignet ist, gegebenenfalls solltest du date besser im Unix Timestamp Format speichern und erst bei der Ausgabe in ein Datum umwandeln

17.01.2007 12:50

5 tomaschko

ich weisst threads is unglücklich gewählt. waren eigentlich mal getrennte tabellen, hab aber dann umgebaut aus diversen gründen.

hab es in timestamp geändert aber wenn ich

$result = mysql_query("SELECT * FROM threads WHERE fid=$fid GROUP BY tid ORDER BY MAX(date) DESC");

eingebe kommt eine fehlermeldung, sowie wenn ich es in die andere abfrage eingebe:

$lresult = mysql_query("SELECT id, topic, user, date FROM threads WHERE fid=$fid AND tid=$thread_id ORDER BY MAX(date) DESC LIMIT 1");
meldung: Warning: mysql_fetch_object(): supplied argument is not a valid MySQL result resource in /srv/www/web79/html/admin/discuss/discuss.php on line 58


In welche der abfragen muss das denn wo rein?

Ist er echt?

17.01.2007 13:28

6 Jörg

MAX() funktioniert nur im Zusammenhang mit GROUP BY. Versuche mal so etwas in der Art:

$result = mysql_query("SELECT id, topic, user, MAX(date) AS maxdate FROM threads WHERE fid=$fid GROUP BY tid ORDER BY maxdate DESC");

Ansonsten kannst du dir die eigentliche MySQL-Fehlermeldung mit
echo mysql_error();
ausgeben lassen.

PS: der Aufbau deine Codes scheint mir etwas unorthodox, so ganz blicke ich da ehrlich gesagt nicht durch (bin wegen einer Erkältung allerdigs auch etwas eingeschränkt im Denken); die Abfragen in eine Schleife zu packen, halte ich auch für nicht unproblematisch, besser wäre es, mit nur wenigen Abfragen zu arbeiten

17.01.2007 14:17 | geändert: 17.01.2007 14:20

7 tomaschko

Ich hab mir mal angewöhnt, ob es nun gut is oder nich, die Sachen erst zum laufen zu bringen und dann zu optimieren. Ich werde mich nächste woche hinsetzen und den code etwas übersichtlicher gestalten und auch funktionen wollte ich für die Abfragen schreiben.

welche Schleife meinst du, die if-else?
Das forum baut auf der indexsite auf, d. h. die if-else-schleife ist notwendig für das einteilen, ob forenübersicht, themenübersicht oder postansicht...Ich sehe darin jetzt nicht wirklich das Problem, aber ich bin ja auch noch "anfänger".

Ist er echt?

18.01.2007 08:01

8 Jörg

Ich meine diese Schleife:

while($row = mysql_fetch_object($result))

Darin werden die Queries $lresult und $num_result ausgeführt. D.h. pro Ergebnisreihe von $result benötigst du noch zwei weitere Queries, das ist etwas sehr viel. Ich würde Datenbank-Queries grundsätzlich außerhalb von Schleifen ausführen (if-else-Konstrukte sind in dem Sinne keine Schleifen)

18.01.2007 10:10 | geändert: 18.01.2007 10:13

9 tomaschko

du meinst ich soll statt der schleife die ausgabe direkt mit $row["..."] statt einer while-schleife oder wie.

ich hab halt durch ein PHP-Kompendium angefangen alles in schleifen auszulesen, weil es in den tutorials dort so gemacht wurde.

ich kann es aber auch ändern, wenn es den code kurzt bzw. besser/schneller arbeitet.

Hat es besondere vorteile wenn ich es so umschreib auf $row["..."]?

Ist er echt?

18.01.2007 10:44 | geändert: 18.01.2007 10:45

10 Jörg

Dass du die Variablen in Schleifen ausliest, ist schon in Ordnung. Problematisch sehe ich es nur an, dass du innerhalb einer solchen Schleife auch Datenbank-Queries hineinstellst. Wenn ich den Code richtig interpretiere, dann werden bei einer Ausgabe von 20 Threads 41 Queries durchgeführt. In meinem Forum wird zum Vergleich nur eine einzlene Query für die Abfrage der Threads benötigt. Wenn ich es richtig verstehe, benötigst du die Ergebnisse von $lresult und $num_result für die Last-Post-Angaben sowie die Anzahl der Posts. Grundsätzlich gibt es zwei Möglichkeiten, diese bereits in der Hauptquery unterzubringen:

1. man fragt diese Daten über die MySQL-Gruppenfunktionen wie MIN(), MAX() und COUNT() ab. Dies ist allerdings schwierig umzusetzen, wenn sowohl die Daten des ersten als auch des letzten Posting abgefragt werden sollen

2. man speichert diese Daten zusätzlich in eigenen Spalten ab, die dann bei jedem Post aktualisiert werden (die Daten sind dann zwar redundant, aber man spart sich u.U. JOIN-Abfragen, die auf die Performance gehen)

18.01.2007 11:43 | geändert: 18.01.2007 11:45