tutorials.de Buch-Aktion 05/2012
ERLEDIGT
NEIN
ANTWORTEN
8
ZUGRIFFE
6317
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    Registriert seit
    Mar 2004
    Ort
    Tiefste Provinz
    Beiträge
    304
    Hallo,
    ich bin ganz neu hier und möchte mal fragen, ob jemand eine bessere Lösung für folgendes Problem weiß:

    Ich möchte in MySQL ein Feld über eine Reihe von Datensätzen neu von 1 bis x durchnummerieren. Es handelt sich um ein Sortierfeld, mit dessen Hilfe der Anwender die Position eines DS in einer Anzeigeliste selbst bestimmen kann.

    Meine Lösung sieht momentan so aus:
    Ich setze voraus, dass das Feld sortorder über alle betroffenen DS nur ganze Zahlen in aufsteigender Reihenfolge enthält. Der User bestimmt nun beispielsweise, dass er Zeile 10 hinter Zeile 5 verschieben möchte. Das Programm schreibt bei Satz 10 den Wert 5.5 in sortorder. Damit nun wieder in allen Sätzen ganze Zahlen stehen, werden per Script alle Sätze selektiert (sortiert nach sortorder) und in einer Schleife wird ein inkrementierender Wert beginnend bei 1 in sortorder geschrieben. In PHP sieht das in etwa so aus:

    PHP-Code:
    $sql "SELECT id,sortorder FROM table WHERE (userid = 'x') ORDER BY sortorder";
    $rst mysql_query($sql$con)
    $i 1;
    while (
    $row mysql_fetch_assoc($rst)) {
        
    mysql_query("UPDATE table SET sortorder = '".$i."' WHERE id = '".$row["id"]."' LIMIT 1"$con)
        
    $i++;
    }
    mysql_free_result($rst); 
    Frage:
    Gibt es für diese Neu-Nummerierung auch eine schnelle, reine SQL-Lösung? Habe bereits mit Variablen experimentiert, was ich mir etwa so vorgestellt habe:

    SET @i=0;
    UPDATE table SET sortorder = (@i := @i + 1) ORDER BY sortorder


    Aber das hat nicht funktioniert. Kann es sein, dass meine MySQL-Version (MySQL-Max 3.23...) das ORDER BY für UPDATE noch nicht unterstützt (die MySQL-Doku http://www.mysql.com/doc/de/UPDATE.html sagt nichts dergleichen). Ohne ORDER BY funktioniert's theoretisch, allerdings werden die Sätze dann in der Reihenfolge ihres Einfügens durchnummeriert.

    Wäre über jegliche Anregung höchst erfreut - vielleicht habe ich mich auch völlig verrannt und es gibt eine ganz simple Lösung...

    Viele Grüße aus dem Allgäu
     

  2. #2
    XChris XChris ist offline Mitglied Brokat
    Registriert seit
    Sep 2003
    Ort
    Weimar
    Beiträge
    373
    Ich würd es so versuchen:

    Neue Tabelle Anlegen mit einem Autoindex. Dann die bestehenden Werte aus der einen tabelle mittels einem INSERT - SELECT kopieren und dabei mit ORDER BY die richtige Reihnfolge beachten.
    Danach wird ich die alte Tabelle Löschen und die neue Umbenennen. (DROP und ALTER)

    Chris
     

  3. #3
    Avatar von aquasonic
    aquasonic aquasonic ist offline Mitglied Brillant
    Registriert seit
    Jan 2004
    Ort
    Schweiz :: Bern
    Beiträge
    942
    Das ist aber noch viel langsamer als seine Lösung. Ich denke schon das es eine solches Statement gibt, dafür ist aber mein SQL wirklich zu schlecht...
     
    MfG AqUaSoN!C

    o Wie man richtig Fragen stellt o

    o Nicht in Problemen sondern in Lösungen denken! o

    o Es gibt 2 Dinge, die sind unendlich: das Universum und die menschliche Dummheit. Aber beim Universum bin ich mir noch nicht ganz sicher. o

    > Meine Linksammlung > http://linksys.aquasonic.ch

    > Mein Wiki > http://wiki.aquasonic.ch

  4. #4
    Registriert seit
    Mar 2004
    Ort
    Tiefste Provinz
    Beiträge
    304
    Hallo Chris,
    danke für die Antwort. Leider ist das nicht genau das was ich will. Habe mich wahrscheinlich nicht ganz klar ausgedrückt - ist aber auch schwer zu beschreiben, das Problem.

    Das Neu-Nummerieren betrifft nicht die ganze Tabelle, sondern immer nur die Datensätze eines bestimmten Benutzers (WHERE userid = 'x'). Es geht auch nicht um die auto_incrementierte Datensatz-ID (Primary Key), ein solches Feld hat die Tabelle natürlich auch, die Sortierung hat mit der ID aber nichts zu tun. Das Neunummerieren ist auch nicht eine einmalige Sache um die Tabelle aufzuräumen, vielmehr würde diese Aktion immer dann gebraucht, wenn ein Anwender einen seiner Listeneinträge hoch oder runteschieben will. Ein Neu-Erstellen der ganzen Tabelle wäre in dieser Situation meiner Ansicht nach etwas zu brutal.

    Trotzdem Danke,
    Martin
     

  5. #5
    Avatar von Thomas Pinske
    Thomas Pinske Thomas Pinske ist offline Mitglied Silber
    Registriert seit
    Jun 2003
    Ort
    Bingen (RLP)
    Beiträge
    56
    Hallo Martin,

    ich bin mir nicht sicher ob MySQL das versteht, aber einen Versuch wäre es wert:

    Code :
    1
    
    UPDATE table SET sortorder=sortorder+1 WHERE sortorder>="NeuePos" AND sortorder<"AltePos"

    "NeuePos" und "AltePos" muss mit der neuen und alten Position des zu verschiebenden DS ersetzt werden.

    Grüße Thomas
     

  6. #6
    vop vop ist offline Mitglied Platin
    Registriert seit
    Mar 2004
    Beiträge
    676
    Hi Resalb,

    wäre es vielleicht eine Idee, eine weitere Spalte für die neue Position zu verwenden, die dann später für die Sortierreihenfolge herangezogen wird?

    UPDATE ... set SortOrder = NeueSortOder?

    BTW:

    Von einem Update .. ORDER BY habe ich generell noch nie etrwas gehört.
    Wozu soll das gut sein? Die Datensätze werden doch nicht sortiert gelagert sondern willkürlich. Eine Sortierung wird ggf. durch einen Index unterstützt, nicht jedoch durch eine Vorgabe, in welcher Reihenfolge einzelne Datensätze aktualisiert werden.

    Oder habe ich Dich total missverstanden?
    vop
     

  7. #7
    Registriert seit
    Jul 2002
    Ort
    Frankfurt (Hessen)
    Beiträge
    2.135
    Der User bestimmt nun beispielsweise, dass er Zeile 10 hinter Zeile 5 verschieben möchte. Das Programm schreibt bei Satz 10 den Wert 5.5 in sortorder. Damit nun wieder in allen Sätzen ganze Zahlen stehen, werden per Script alle Sätze selektiert
    ok deine 5 haste sicher noch als Variable

    update table set sortorder = floor(sortorder)+1 where sortorder > '$var' and userid = '$userid'

    und schon sind alle einträge um eins hochgezählt
     

  8. #8
    Registriert seit
    Mar 2004
    Ort
    Tiefste Provinz
    Beiträge
    304
    @Thomas,

    Danke für den Tipp, das sieht erst mal vielversprechend aus. Mals seh'n ob ich das richtig verstanden habe:
    In dem Beispiel, wo Zeile 10 hinter Zeile 5 verschoben werden soll, würde zunächst in Satz 10 bei sortorder 5.5 reingeschrieben. Dann würde
    Code :
    1
    
    UPDATE table SET sortorder = FLOOR(sortorder+1) WHERE sortorder >= '5.5' AND sortorder < '10' AND userid = 'x'
    nur die Datensätze 5.5 bis 9 neu nummerieren, alle anderen sind ja nicht betroffen, das FLOOR is wohl zus. nötig, damit aus 5.5 nicht 6.5 sondern 6 wird.
    Wie ist das dann aber in umgekehrter Richtung? Schiebe 5 hinter 10, schreibe also 10.5 in sortorder von 5. In dem Fall müsste das also umgedreht werden:
    Code :
    1
    
    ... WHERE sortorder > 'altePos' AND sortorder < 'neuePos+1'
    Das ist ja kein Problem, dann gibt's halt 2 unterschiedliche SQL-Statements.

    Super, ich denke das ist es! Werde das gleich so machen. Vielen Dank.

    @melmager:
    Hab' Dein Posting grade erst gesehen. Das ist im Prinzip das was Thomas vorgeschlagen hat, nur "nach oben hin offen". Danke trotzdem.

    @vop:
    Das ORDER BY im Zusammenhang mit UPDATE kannte ich bisher auch nicht. Ich fand dann den Satz "Wenn die ORDER BY-Klausel angegeben ist, werden die Zeilen in der angegebenen Reihenfolge aktualisiert" in der MySQL-Doku unter http://www.mysql.com/doc/de/UPDATE.html und dachte, das könnte mir helfen. War aber ein Irrweg, wo die Lösung doch so einfach ist.

    Grüße,
    Martin
     

  9. #9
    Christian Proske Christian Proske ist offline Grünschnabel
    Registriert seit
    May 2011
    Beiträge
    1
    SET @c := 0;
    UPDATE test SET platz = ( SELECT @c := @c + 1 ) ORDER BY id ASC;
    gefunden auf: http://www.cix-blog.de/thm/MySQL-Upd...eu-nummerieren
     

Ähnliche Themen

  1. DB2 Version 5.4 Update auf mehrere Sätze mit inner Select auf andere Datei
    Von fuDDel im Forum Relationale Datenbanksysteme
    Antworten: 2
    Letzter Beitrag: 24.08.10, 08:24
  2. MYSQL Feld - mehrere Einträge?!
    Von maxn im Forum Relationale Datenbanksysteme
    Antworten: 6
    Letzter Beitrag: 23.04.08, 22:20
  3. MySQL DB Sätze Verschieben
    Von fragger1991 im Forum Relationale Datenbanksysteme
    Antworten: 2
    Letzter Beitrag: 03.10.07, 12:28
  4. Antworten: 2
    Letzter Beitrag: 17.09.07, 17:14