MySQL Sortierung (Für Profis)

  • Hallo ^^


    Hier mal ein etwas komplizierteres Anliegen.
    Da ich durch einen Datenzugriff auf den MySQL Server eh schon mit dem Server verbunden bin, wollte ich die Sortierung der Daten dort auch gleich ablaufen lassen.
    Davor hatte ich dies mit PHP geregelt, indem ich ALLE Daten gezogen habe und dann denn Array über usort nach dem 'created_at' und 'id' keyword sortieren lassen habe.


    Mein Ziel ist, die Daten zu splitten, um verschiedene Seiten zu erstellen.


    Da ich aber nicht alle Daten ziehen will (verbraucht ja extrem viel Performance), sondern mit dem MySQL Keyword limit arbeiten möchte, muss ich bevor LIMIT überhaupt ab einem bestimmten Wert aufhört, die Daten zu holen, diese vorher sortieren.


    Weiß jemand, wie das möglich ist?


    Bisher habe ich folgendes:



    Das Problem hierbei ist, dass die ID unabhängig vom Erstellungsdatum ist. Normalerweise ist das Erstellungsdatum ja immer, je größer die ID ist, jünger. Doch ich will, dass es auch funktioniert, wenn man das Erstellungsdatum ändert.


    so kann es sein, dass die ID 3 später erstellt wurde, als ID 4 (normalerweise andersherum).


    Das Problem in meiner Abfrage ist, dass man, wenn man checkt, ob eine ID größer als die letzte ist, das nicht mehr geht. Gerade wegen dem eben beschriebenen Problem.


    Generell will ich die letzte ID der Daten haben, die es auf einer Seite gibt (Seitengröße: 28 Daten).
    Und falls mehrere Daten zur gleichen Zeit erstellt wurden, muss ich ja noch die ID mit überprüfen. Nur durch den Eintrag in die WHERE-Klausel mit id < $lastId unterdrückt man ja die kleineren IDs, die aber ggf ein neueres Erstellungsdatum haben...


    Ich weiß, das ist sehr kompliziert und ich zerbreche mir hierbei auch langsam den Kopf ^^


    Mit freundlichen Grüßen,
    Alf21

  • Also dein Ziel ist es eine Pagination mit 28 Post (Bildern?) pro Seite zu machen und das ganze mit einer möglichst schlauen SQL?

    seekrass approved
    4x vom Discord geflogen


    shoxinat0r 4
    dennismitzwein 2
    Trooper[Y] 2
    maddin 1
    Unbekannter Discord Kick 2
  • Genau ... :/


    Der oberen Code habe ich halt damit versucht:


    SELECT id, created_at FROM bilder WHERE ORDER BY created_at DESC, id ASC LIMIT $limit; (1. Aufruf (Seite 0))
    SELECT id, created_at FROM bilder WHERE id > $lastId AND created_at < $lastNewest ORDER BY created_at DESC, id ASC LIMIT $limit; (n>0 Aufruf (Seite n))


    zuerst werden die ältesten Daten geladen und diese nach ID sortiert. Dann, wenn das Limit erreicht ist, wird die letzte ID gespeichert und das älteste Datum (Timestamp).


    Wenn nun ein neuer Aufruf kommt (n>0) dann bekommt er alle Einträge, die jünger als der letzte ist und eine größere ID haben (Da die Liste vorher sortiert wurden.)


    Wenn nun aber ein noch jüngerer Eintrag kommt, logisch (soll es ja), dann nimmt er nur alle, mit einer GRÖSSEREN ID, was die kleineren ausschließt :/


    Ist sowas überhaupt mit MySQL möglich? :D


    Ich meine, ich kann auch keine in der Select Abfrage erstellte Variable in der Where Klausel nutzen, ohne gewrappte Abfragen zu erstellen...


    Ich könnte mir vorstellen, dass das auch nur über gewrappte Aufrufe möglich ist, nur finde keinen Ansatz.

  • Du sagst ja 28 Post pro Seiten sortiert nach Datum Absteigend.


    Beispielsweise so würde ich das lösen.
    Die Grundlegende query sieht wie folgt aus.

    SQL
    SELECT id, created_at FROM bilder ORDER BY created_at DESC LIMIT $seite,$limit;

    Zur erklärung: Das LIMIT bezweckt in diesem Fall das die ersten $limit(28) Bilder nach den ersten $seiten Bilder genommen werden. D.h das würde ungefähr das folgende erzeugen:


    Page 1 -> LIMIT 0,28;
    Page 2 -> LIMIT 28,28;
    Page 3 -> LIMIT 56,28;


    Die Seite Variable "berechnet" sich wie folgt. $currentPage steht für die Seite auf dem sich der User gerade befindet. In der Regel steht das ja in der URL (index.php?page=2)
    Zu Beachten ist dass die meisten Paginations bei 1 Anfangen und nicht bei 0. Ggf. sonst das -1 entfernen.

    PHP
    $seite = (($currentPage - 1) * 28;


    Die ID's sind dir eigentlich relativ, da du ja nur nach dem Datum gehst. Die ID's kommen hald nicht Sortiert zurück aber in meinem Fall ist die "Bild-ID" sowieso unnötig da nur die Page eine rolle spielt.

    seekrass approved
    4x vom Discord geflogen


    shoxinat0r 4
    dennismitzwein 2
    Trooper[Y] 2
    maddin 1
    Unbekannter Discord Kick 2
  • Sone simple Antwort hättest du mir nicht zeigen dürfen, dafür muss ich mich gerade selbst auslachen :D


    So viel bereits mit MySQL gemacht, und nie mitbekommen, dass man Limit auch als Interval abfragen kann...


    http://stackoverflow.com/questions/5767479/mysql-limit-range


    Vielen Dank @toor, muss zwar mein ganzes System umbauen, aber hab dafür was neues dazugelernt :) und noch so praktisch ^^