[MySQL/PHP] Zeige nachfolgende Datensätze an, aber sortiert

  • Sonstige

Es gibt 30 Antworten in diesem Thema. Der letzte Beitrag () ist von Marcus Gräfe.

    [MySQL/PHP] Zeige nachfolgende Datensätze an, aber sortiert

    Ich arbeite derzeit an einer Problemstellung, für die ich noch keine gute Lösung habe. Es geht mir nur um einen Ansatz, nicht um Programmiercode (der würde natürlich auch helfen ;)).

    Folgendes Problem:

    In MySQL habe ich eine Tabelle mit den Feldern "ID, "NR" und "TITEL". Mittels PHP zeige ich mir insgesamt 10 Datensätze an, und zwar absteigend sortiert nach NR und danach aufsteigend nach TITEL. Soweit, so gut.

    Nun möchte ich gezielt einen Datensatz aufrufen können und die 9 nachfolgenden Datensätze auflisten (also wieder insgesamt 10). Und da liegt das Problem, denn:

    Wie kann ich die nachfolgenden Datensätze, also die Nachbarn, ermitteln? Ich kann nicht where ID >= %EINGABE_ID% limit 10 machen, denn die ID sagt gar nichts über die Nummer oder den Titel aus, nach denen ich sortieren möchte.

    Ich mache es jetzt gerade so, was grundsätzlich funktioniert, aber ich berücksichtige dabei nicht die Titelsortierung:

    PHP-Quellcode

    1. $where_nr = '';
    2. $result = $db->query("select NR
    3. from FILMLISTE
    4. where ID = $getid");
    5. $row = $db->fetch_array($result);
    6. $where_nr = $row['NR'];
    7. $where_nr = ' and NR <= ' . $where_nr;
    8. // Hier wird dann "$where_nr" in eine SQL-Anweisung als Zusatzbedingung eingebaut

    Hat jemand eine Idee? Ich kann ja nicht mittels "and" noch den Titel einbauen, das würde u. U. nicht alle Datensätze liefern.
    Besucht auch mein anderes Forum:
    Das Amateurfilm-Forum
    mir fällt dafür keine lösung direkt ein ... aber mir stellt sich eine frage: wofür?
    wenn du paging machen willst dann würde ich das nicht so lösen... dort könntest du dann mit limit arbeiten und dein problem wäre gelöst

    ansonsten fällt mir gerade noch ein, könntest du es via javascript lösen
    du generierst dir in php eine komplette liste als JSON object oder xml und holst dir die mit JS...
    Genau, für "Paging", also seitenweises navigieren. Und wie gesagt, limit ist nicht möglich. Denn damit bekomme ich ja nur die ersten 10 Datensätze meiner Abfrage. Die Abfrage liefert aber immer ALLE Datensätze, also hunderte bis tausende.

    Javascript ist eher schlecht, weil die Daten dann nicht aktuell sind.

    Bisher ist mein bester Einfall eine Stored Procedure. Aber ich halte die für zu langsam, weil immer alle Datensätze durchlaufen werden müssen.
    Besucht auch mein anderes Forum:
    Das Amateurfilm-Forum
    Zugegeben, so richtig erschließt sich mir die Problemstellung (gerade) nicht, aber hilft das hier vielleicht?:

    techonthenet.com/sql/order_by.php

    Es geht um mehrfaches Sortieren innerhalb einer Query, Paging sollte sich auch gleich in der Query machen lassen.

    Edit: falls es beim Paging Probleme gibt, hierzu gab es neulich eine relativ ausführliche Diskussion:
    [PHP] Anzeige pro Seite begrenzen
    „Was daraus gefolgert werden kann ist, dass jeder intelligentere User sein Geld lieber für Bier ausgibt, um einen schönen Rausch zu haben, und nicht dieses Ranzprodukt.“

    -Auszug aus einer Unterhaltung über das iPhone und dessen Vermarktung.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Lukas“ ()

    Paging macht man anders. Du holst dir zuerst die Anzahl der Datensätze. Dann teilst sie durch die Anzahl der auf einer Seite angezeigten Datensätze z.B. 15 rundest ab und hast somit die Anzahl der zu erstellenden Seiten.
    Nun gehst du in einer Schleife von 0 bis Anzahl_Seiten und erstellst einen Link wo die SeitenNummer übergeben wird.
    Die Abfrage dann machste mit LIMIT $start, $AnzahlDatensätze
    Das Problem ist nicht das seitenweise Ausgeben aller Datensätze, sondern das Springen zu einer bestimmten ID und Ausgeben dessen 9 Nachbarn.

    Also ich habe 100 Datensätze und möchte gezielt den mit der ID X haben. Der kann sich irgendwo befinden, also an Position 1, 20, 50, 99, usw.

    Ich kann da kein limit verwenden.

    Edit: Noch ein paar Beispiele, warum es nicht geht:

    select * from tabelle where ID = 1 limit 1,10 => Liefert nur einen Datensatz
    select * from tabelle where ID > 1 limit 1,10 => Liefert zwar 10 Datensätze inkl. dem gesuchten, aber die 9 anderen sind nicht die, die ich haben will, da ich nicht nach ID, sondern nach NR und TITEL sortiere.
    select * from tabelle where NR < "123" limit 1,10 => Liefert zwar 10 Datensätze inkl. dem gesuchten und die Sortierung stimmt, aber wenn es doppelte Nummern gibt wird nicht die Sortierung nach dem TITEL berücksichtigt.
    Besucht auch mein anderes Forum:
    Das Amateurfilm-Forum

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Marcus Gräfe“ ()

    Würdest du richtig wissen wie man die SQL anwendet, wüsstest du dass es für so ziemlich alles eine Lösung in einem Query gibt.
    Also egal was du brauchst: Sag an und wir können dir einen Query geben (der schneller und somit sinnvoller ist).
    Ich habe über das Problem mittlerweile so viel nachgedacht, dass ich sicher bin, dass es auf keinen Fall mit einer Query zu erreichen ist. Auf MySQL-Ebene höchstens mit einer Stored Procedure. Oder direkt in PHP.

    Und was soll ich ansagen? Das Problem ist doch klar definiert: Zeige mir die 9 Nachbarn einer sortierten Datenausgabe.

    Edit:
    Hier mal eine stark abgespeckte Version meiner Tabelle (es handelt sich um eine andere, die nicht nach NR desc, TITEL sortiert wird, sondern nach NR_STR, NR_INT desc, BEZEICHNUNG1:

    SQL-Abfrage

    1. drop table if exists MEDIENLISTE;
    2. create table MEDIENLISTE (
    3. ID integer unsigned not null auto_increment, /* Eindeutige (interne) ID des Datensatzes */
    4. NR varchar(10) comment 'Nummer', /* Nummer des Datenträgers */
    5. NR_INT integer unsigned, /* Nummer als reine Zahl zum Sortieren */
    6. NR_STR varchar(10), /* Nummer als reiner String zum Sortieren */
    7. BEZEICHNUNG1 varchar(255) not null comment 'Bezeichnung 1',
    8. primary key (ID),
    9. ) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_unicode_ci;

    Und hier ein paar Beispieldatensätze, die ich mir mal eben ausgedacht habe:

    SQL-Abfrage

    1. insert into MEDIENLISTE (NR, NR_INT, NR_STR, BEZEICHNUNG1) values ("A001", 1, "A", "Test 1");
    2. insert into MEDIENLISTE (NR, NR_INT, NR_STR, BEZEICHNUNG1) values ("X003", 3, "X", "Test 100");
    3. insert into MEDIENLISTE (NR, NR_INT, NR_STR, BEZEICHNUNG1) values ("Z004", 4, "Z", "A Test 1");
    4. insert into MEDIENLISTE (NR, NR_INT, NR_STR, BEZEICHNUNG1) values ("B001", 1, "B", "X Test 1");
    5. insert into MEDIENLISTE (NR, NR_INT, NR_STR, BEZEICHNUNG1) values ("F010", 10, "F", "B Test 1");
    6. insert into MEDIENLISTE (NR, NR_INT, NR_STR, BEZEICHNUNG1) values ("001", 1, "", "xyz Test 100");
    7. insert into MEDIENLISTE (NR, NR_INT, NR_STR, BEZEICHNUNG1) values ("002", 2, "", "");
    8. insert into MEDIENLISTE (NR, NR_INT, NR_STR, BEZEICHNUNG1) values ("100", 100, "", "bla");

    Die zugehörige SQL-Abfrage lautet:

    SQL-Abfrage

    1. select ID, BEZEICHNUNG1, NR
    2. from MEDIENLISTE
    3. order by NR_STR asc, NR_INT desc, BEZEICHNUNG1
    4. limit 10

    Die liefert erstmal die ersten 10 in meiner Sortierreihenfolge. Nun möchte ich per ID gezielt alle 9 Nachfolger von dem Datensatz mit der angegebenen ID aufrufen. Aber mit der richtigen Sortierung.
    Besucht auch mein anderes Forum:
    Das Amateurfilm-Forum

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „Marcus Gräfe“ ()

    Aber wie sollen die Nachbarn ermittelt werden? Anhand der ID? Anhand der Nummer? Wenn z.B. ein Datensatz mit der ID 5 suchst, dieser hat die Nummer 23, willst nun die folgenden Datensätze anhand der Nummer haben? Also 24,25,26,... ?? Kommen die Nummern öfters vor?
    Siehe wieder mein Edit (ihr seid zu schnell). ;)

    Ja, ich will die nachfolgenden Datensätze anhand der Nummer haben. Aber eben nicht nur anhand einer Nummer, sondern anhand von insgesamt drei Sortierkriterien. Das ist das Problem. Bei einem Sortierfeld wäre es fertig (siehe 1. Post). Wobei da noch das Paging fehlt.

    Jedes Feld kann beliebig oft doppelt und mehrfach vorkommen. Aber es ist extrem unwahrscheinlich, dass alle drei Sortierfelder identisch sind (eigentlich unmöglich von der Bedienung her, aber nicht technisch unmöglich).
    Besucht auch mein anderes Forum:
    Das Amateurfilm-Forum
    Der BETWEEN-Operator könnte dir helfen.

    Bsp:

    SQL-Abfrage

    1. SELECT *
    2. FROM suppliers
    3. WHERE supplier_id BETWEEN n AND n+9;

    techonthenet.com/sql/between.php

    bin mir allerdings nocht sicher ob's funktioniert: Ausprobieren ;)
    /nicht getestet
    "between" ist mir natürlich ein Begriff, aber auch das geht nicht. Denn welches Feld würde ich da angeben? ID? Weder ID noch eines der Sortierfelder ist fortlaufend, so dass man nicht einfach "+9" machen kann.
    Besucht auch mein anderes Forum:
    Das Amateurfilm-Forum
    so glaub ich hab die lösung ...

    du holst dir die ersten 10 beiträge via LIMIT 0, 10, danach wählst du beispielsweise das 8. item aus und baust ein neuen query mit dem selektieren index und + 10 in einem LIMIT query :D

    1. SELECT .... ORDER BY ... LIMIT 0, 10
    2. user selektiert das item an position 8 (=index | nicht mit deinem attribut id o.ä. verwechseln, der wert entspricht dem in deiner view!)
    3. neuer query SELECT ... ORDER BY ... LIMIT $INDEX, $INDEX+10

    ist zwar nicht wirklich das gelbe vom ei aber es sollte funktioniert :)
    Und woher bekomme ich den Index? Der User ruft den zu bearbeitenden Datensatz womöglich aus einem anderen Formular auf. D.h. ich habe wirklich nur eine ID des Zieldatensatzes und ansonsten meine sortierte Liste mit allen Datensätzen.
    Besucht auch mein anderes Forum:
    Das Amateurfilm-Forum

    Marcus Gräfe schrieb:

    Nun möchte ich gezielt einen Datensatz aufrufen können und die 9 nachfolgenden Datensätze auflisten (also wieder insgesamt 10)


    Da kann ich dir nicht folgen. Erklärung bitte :s

    #Edit
    Mal angenommen du hast einen Query der 10 Datensätze liefert, du willst aber nur den sechsten Datensatz, als Beispiel. Liege ich da richtig?
    Codebeispiel:

    PHP-Quellcode

    1. $objQuery = mysql_query("select * from mytable order by id limit 0,10;");
    2. $intIndex = 0;
    3. while($arrRow = mysql_fetch_array($objQuery))
    4. {
    5. if($intIndex == 5) //sechsten datensatz
    6. {
    7. echo "datensatz gefunden :D<br />";
    8. }
    9. echo "row: ".$arrRow['id']."<br />";
    10. $intIndex ++;
    11. }

    Und das willst du direkt in einem Query haben?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „BeefyX“ ()