Nach Datum sortieren

lisali

Erfahrenes Mitglied
Hallo,

ich habe da so eine ShoutBox und würde gerne die Einträge nach Datum sortiert anzeigen lassen, und zwar in der Form:

[ 03.02.2010 ]
<eintrag 5>
<eintrag 4>
<eintrag 3>

[ 01.01.2010 ]
<eintrag 2>
<eintrag 1>


Also, es soll immer wenn es ein neuer Tag (also ein anderes neues Datum) ist, immer das Datum über den Einträgen des Datums angezeigt werden.

Ich habe jetzt diesen Code:

PHP:
$query = mysql_query("SELECT `user_id`,`text`, 
DATE_FORMAT(`date`,'%d.%m.%Y') AS shortdate, 
DATE_FORMAT(`date`,'%H:%i') AS time, 
TIMESTAMPDIFF(SECOND,`date`,NOW()) AS sec 
FROM `shoutBox` ORDER BY `id` DESC");

while ($shoutBox = mysql_fetch_array($query)) {
	
	$wrapText = $shoutBox['text'];
	$text = wordwrap($wrapText, 18, "-<br \>\n", true);
	
	$data = mysql_fetch_array(mysql_query("SELECT `username` FROM `users` WHERE `id`='".$shoutBox['user_id']."'"));

	if ($shoutBox[sec]>=86400){ echo "<span class='colorYellowBG rb3'>".$shoutBox[shortdate]."</span><br /><br />"; }

Ich würde eigentlich nur gerne wissen was für eine if-Bedingung ich bräuchte, damit ich das so machen kann wie ich es mir vorstelle. Oder es gibt dazu direkt ein SQL-Statement!?

Vielen Dank im Voraus!
 
Du könntest das jeweilige Datum in einer Variablen $old_date speichern und bei jedem Schleifendurchlauf vergleichen, ob ein neues Datum vorliegt.
Desweiteren würde ich bei Assoziativen arrays den Schlüssel in Anführungszeichen setzen ;)
 
Eigentlich frage ich mich mehr wie genau ich das mache... also die Überprüfung!?

Welchen Schlüssel meinst du jetzt damit und wieso würdest du das tun?
 
Also die Schlüssel eines Arrays sind ja die "Sachen" die in den eckigen Klammern stehen.
PHP:
$array["schluessel"];

Die Überprüfung könntest du in etwa so vornehmen:
PHP:
$query = mysql_query("SELECT `user_id`,`text`, 
DATE_FORMAT(`date`,'%d.%m.%Y') AS shortdate, 
DATE_FORMAT(`date`,'%H:%i') AS time, 
TIMESTAMPDIFF(SECOND,`date`,NOW()) AS sec 
FROM `shoutBox` ORDER BY `id` DESC");

$current_date = "";
while ($shoutBox = mysql_fetch_array($query)) {
    if( $current_date != $shoutBox["shortdate"] ){
      $current_date = $shoutBox["shortdate"]; 
      echo "[".$current_date."]";
    }
    $wrapText = $shoutBox['text'];
    $text = wordwrap($wrapText, 18, "-<br \>\n", true);
    
    $data = mysql_fetch_array(mysql_query("SELECT `username` FROM `users` WHERE `id`='".$shoutBox['user_id']."'")); // das würde ich eher in den ersten Query mit hinein packen (warscheinlich mit LEFT JOIN da du sonst ziemlich viele DB-Abfragen hast

    if ($shoutBox["sec"]>=86400){ echo "<span class='colorYellowBG rb3'>".$shoutBox["shortdate"]."</span><br /><br />"; }
 
Du musst erst klarstellen, wieviele verschiedene Tage pro Seite angezeigt haben möchtest. Durch diese Range kannst du dann sehr leicht über ne Schleife einfach die Einträge ausgeben und bist fertig, denn du musst überlegen, dass etwas unüberdachtes im Script bei sehr hohen Besucherzahlen inne Hose gehen kann.
 
Hi,

noch einige nützliche Tipps - versuche sämtliche unnützen Operationen in der Datenbank zu vermeiden. Dazu zählen zum Beispiel die Konvertierung von Timestamp in Datum, Zeit oder was auch immer (wie gesagt sofern vermeidbar). Mache das in PHP. Bei großen Web Apps ist IMMER der DB-Server der Flaschenhals. Daher sollte der DB-Server so viel Arbeit leisten wie nötig, aber so wenig wie möglich.

Hier mal ein Beispiel (fetch_array entfernt sry / Benutzernamen Abfrage gejoint):
PHP:
$res = mysql_query ("
	SELECT sb.user_id, u.username, sb.text, sb.date
	FROM shoutBox AS sb 
	LEFT JOIN users AS u ON u.id = sb.user_id # LEFT kannst du unter Umständen entfernen, falls Gäste nix posten dürfen
	ORDER BY sb.id DESC
");

$dateBefore = null;
while (list ($user_id, $username, $text, $datetime) = mysql_fetch_row ($res))
{
	$ts 	   = strtotime ($datetime);
	$shortdate = strftime ("%d.%m.%Y", $ts);
	$time 	 = strftime ("%H:%M", $ts);
	$sec 	  = now() - $ts; // brauchste die noch? sonst raus
    $text 	 = wordwrap ($text, 18, "-<br \>\n", true);

    if ($dateBefore!=$shortdate)
	{
		echo "<span class='colorYellowBG rb3'>$shortdate</span><br /><br />";
		$dateBefore = $shortdate;
	}
	echo "$time, $username - $text<br />";
}

Grüße BN
 
Hey,

vielen Dank für die Tipps. An solchen Tipps liegt mir sehr viel! Ich hätte da gleich noch eine Frage dazu. Also, ich habe so grob vor einiger langer Zeit mal irgendwas "programmiert" damals, wo ich noch unerfahrener war als jetzt. Und da habe ich jetzt die User-Tabelle übernommen und die hat echt viele Spalten (Selbtbeschreibung, ID, Signup-Datum, Login-Zeit, Name, usw usf).

Und jetzt hab ich entdeckt, dass ich damals auch eine extra Zeit-Table gemacht hab, namens users_time und dort stehen 3 Spalten: User-ID, Login, Logout. Also, welcher User hat sich wann zuletzt eingeloggt und wann zuletzt ausgeloggt.

Und ich prüfe mit jedem Seitenklick eines Benutzers: Ist Benutzer registriert (hat Session)? Wenn ja, wird das in die Time-Table geschrieben.

Jedenfalls frage ich mich gerade warum ihc das gemacht hab, aber ich hab in Erinnerung, dass mir empfohlen wurde, dass es besser ist und eine Tabelle in einer DB nicht so viele Spalten haben sollte. Stimmt das denn?

Ich meine, ist das nicht eigentlich Blödsinn, weil ich doch dann viel mehr DB-Abfragen machen müsste? Auch viel mehr einzelne Updates, Inserts, usw?
 
Das passt schon. Du wirst ja beispielsweise immer nur die Session am Leben halten oder den letzten Login/logout weg schreiben. Alle anderen Daten fässt du bei diesen Aktionen nicht an.

Tabellen sollten so aufteilt werden, dass es sinnvoll ist. Es ist jedoch so, dass breite Tabellen (viele Spalten) mit vielen Daten (viele Records) schlecht für die Performance des DB-Servers sein können (nicht müssen). Der DB-Server kann unter Umständen Zwischenergebnisse von Abfragen auf diese Tabellen(n) auf Grund der Datenmenge nicht mehr in den Speicher legen. Dann schreibt er die Daten auf Festplatte (temporary table). Für die Geschwindigkeit bedeutet das einen massiven Einbruch (Latenzzeit + Lese/Schreibgeschwindigkeit = Katastrophe). Dies gilt es zu vermeiden.

Eine bewährte Technik ist, Felder variabler Länge von Feldern fixer Länge zu trennen, sprich in verschiedene Tabellen zu packen. Felder fester Länge sind z.B. DATE, INT oder CHAR. Felder variabler Länge sind z.B. VARCHAR, TEXT oder BLOB. Es hilft auch zu wissen, dass der Query Cache von MySQL eine Abfrage so lange im Cache vor hält, bis ein Datensatz irgend einer Tabelle der gecachten Abfrage geändert, gelöscht oder hinzugefügt wird. Daraus resultierend lässt sich also sagen, dass es sinnvoll ist Dinge, die sich ständig ändern in eine und Dinge die nahezu fix sind in eine andere Struktur zu packen.

Wie auch immer man es dreht, jede Datenbank ist gepaart mit dem dazugehörigen Programm ein individueller Fall und auch als solcher zu betrachten.

Grüße BN
 
Also, worauf bezogen passt das jetzt schon? Du meinst, dass ich diese seperate Zeit-Tabelle erstellt habe?

Okay, das werde ich mir versuchen zu merken. Ist es eigentlich möglich INSERTS oder UPDATE mit einem SQL-Befehl mit einer Art Join wie beim Select-Befehl mit sozusagen einer SQL-Operation zu bewerkstelligen?

Danke nochmal für die hilfreichen Antworten von dir!
 
Zurück