Didi: Tabellen Sortierung selbst beeinflussen

Hallo,

ich habe ff. Problem.

Meine Tabelle besteht aus div. Feldern (ID, Datum, Text....) eines davon nehme ich her um eine benutzerdefinierte Sortierung der Ausgabe zu gewährleisten. (Feld: Sortierzahl)
Bei Neueintrag div. Daten in die Datenbank bekommt dieses Feld eine nächsthöhere Zahl eingetragen. Wie realisiere ich aber zu einem späteren Zeitpunkt, daß ich einen Eintrag weiter hoch bringe, oder nach hinten sortiere.
Beispiel:
ID:1,Text:Blabla,Sortierzahl:1
ID:2,Text:Blabla,Sortierzahl:2
ID:3,Text:Blabla,Sortierzahl:3
ID:4,Text:Blabla,Sortierzahl:4
ID:5,Text:Blabla,Sortierzahl:5

Ich will nun also den Eintrag mit der Sortierzahl 4 auf 3 ändern und 3 auf 4.

Oder nachdem ein paar Einträge entfernt wurden:
ID:1,Text:Blabla,Sortierzahl:1
ID:2,Text:Blabla,Sortierzahl:2
ID:3,Text:Blabla,Sortierzahl:3
ID:4,Text:Blabla,Sortierzahl:4
ID:6,Text:Blabla,Sortierzahl:6
ID:7,Text:Blabla,Sortierzahl:7
ID:8,Text:Blabla,Sortierzahl:8
ID:11,Text:Blabla,Sortierzahl:11
ID:12,Text:Blabla,Sortierzahl:12
ID:14,Text:Blabla,Sortierzahl:14
ID:15,Text:Blabla,Sortierzahl:15

Ich will nun den Eintrag mit der Sortierzahl 11 vor den Eintrag mit der Sortierzahl 8 verschieben. (Die Einträge dazwischen sind schon gelöscht)

Ich hoffe das war einigermaßen verständlich und mit kann jmd. helfen.

  1. Hallo Didi,

    nimm einfach von Anfang an Sortierzahlen 10,20, ... statt 1,2,...
    Dann hast Du Spielraum zum Zwischenschieben und Tauschen.
    Wenn Du z.B. 3 und 4 (also 30 und 40) tauschen möchtest, kannst Du ohne Konflikte die 30 auf 41 und die 40 auf 31 setzen. Wenn Du willst, kannst Du natürlich danach noch die 41 wieder auf 40 und die 31 auf 30 setzten, aber notwendig ist das nicht.

    Gruß Mia

    1. Danke habe es doch mit 1,2,3 lösen können. Ich lese halt die ID der zwei zu tauschenden Werte aus und Update diese Werte dann gegenverkehrt. Also zwei Updates, die ich mit PHP ausführe. Direkt im mySQL hab ich keine Lösung gefunden.

      Gruß Didi

      Hallo Didi,

      nimm einfach von Anfang an Sortierzahlen 10,20, ... statt 1,2,...
      Dann hast Du Spielraum zum Zwischenschieben und Tauschen.
      Wenn Du z.B. 3 und 4 (also 30 und 40) tauschen möchtest, kannst Du ohne Konflikte die 30 auf 41 und die 40 auf 31 setzen. Wenn Du willst, kannst Du natürlich danach noch die 41 wieder auf 40 und die 31 auf 30 setzten, aber notwendig ist das nicht.

      Gruß Mia

  2. Hello,

    am einfachsten ist es zum Einfügen eines Satzes sicherlich, alle folgenden um eins zu erhöhen und den Satz dann in die "Lücke" einzufügen.

    Das lässt sich leicht mit zwei Statements machen

    update tabelle set sortfeld = sortfeld + 1 where sortfeld > $neueposition
       insert into tabelle set .... sortfeld = $neueposition

    Diese beiden Statements müssen aber durch ein Lock geklammert werden.
    Das kann man entweder durch ein explizites Locken der Tabelle erreichen, oder aber durch ein Common (Transaktion), wenn die DB das leistet.

    z.B.: http://dev.mysql.com/doc/refman/5.1/en/set-transaction.html

    $sortfeld sollte einen Unique Index tragen, damit es keine Doppeleinträge gibt.
    Das führt dann aber zu Problemen beim "Weiterrücken". Das Weiterrücken müsste dann von hinten nach vorne stattfinden

    update tabelle
       set sortfeld = sortfeld + 1
       where sortfeld > $neueposition
       order sortfeld desc

    Ich bin mir aber nicht sicher, dass das bei allen DBMS funktioniert.
    Manchmal darf man die unter Order stehende Spalte nicht updaten, da der Indexzugriff dann zirkuläre Verläufe erzeugen könnte.

    Harzliche Grüße vom Berg
    http://bergpost.annerschbarrich.de

    Tom

    --
    Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
    Nur selber lernen macht schlau
    Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)

    1. Danke habe es doch mit 1,2,3 lösen können. Ich lese halt die ID der zwei zu tauschenden Werte aus und Update diese Werte dann gegenverkehrt. Also zwei Updates, die ich mit PHP ausführe. Direkt im mySQL hab ich keine Lösung gefunden.

      Gruß Didi

  3. yo,

    integer zahlen dafür zu nehmen, ist eine sehr unglückliche entscheidung. ich würde dafür einen datums/zeitwert nehmen. das sollte schon viele deiner probleme lösen.

    Ilja

    1. Hello,

      integer zahlen dafür zu nehmen, ist eine sehr unglückliche entscheidung. ich würde dafür einen datums/zeitwert nehmen. das sollte schon viele deiner probleme lösen.

      Der ist auch granular also endlich.
      Das verkompliziert nur die Übersichtlichkeit.

      Und wenn der OP die lfd. Nummer sogar anzeigen lassen will, was oft sinnvoll ist, kann er mit dem Datums-Zeitwert auch nicht so schnell glücklich werden.

      Harzliche Grüße vom Berg
      http://bergpost.annerschbarrich.de

      Tom

      --
      Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
      Nur selber lernen macht schlau
      Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)

      1. yo,

        Der ist auch granular also endlich.

        das hängt von der fachlichkeit ab, letztlich will ich ja nach einen kriterium sortieren, zum beispiel ein erstelldatum. und dann ist es auch kein problem, wenn zeitgleichheit vorkommt. aber um auch das zu vermeiden, könnte man den pk noch als zweites sortier-kriterium dazu nehmen, dann wäre es immer eindeutig.

        Und wenn der OP die lfd. Nummer sogar anzeigen lassen will, was oft sinnvoll ist, kann er mit dem Datums-Zeitwert auch nicht so schnell glücklich werden.

        laufende nummern lassen sich ganz einfach erzeugen, weil ich mich selbst nicht mehr um die nummerierung kümmern muss, sondern die reihenfolge der datensätze aus der abfrage als nummerierung nehmen kann.

        Ilja

        1. Hello,

          es ging hier aber wohl um die Möglichkeite der freien Anordnung von Elementen in einer Sortierung.

          Ein gutes Besipiel sind meine Tragelisten für Zeitungsausträger.

          Da sind erst einmal die Straßenabschnitte (zwischen ermittelten Knotenpunkten) in eine Reihenfolge eingeordnet und dann innerhalb der Abschnitte noch die Adressaten. Wenn ein neuer hinzukommt, muss der an der passenden Stelle auf der Liste erscheinen, damit der Austräger nicht nachher doppelte Wege hat.

          So ein Eintrag hat absolut nichts mit dem Zeitpunkt der Eintragung zu tun und Doubletten darf es eigentlich auch nicht geben. Das ist zwar bei Mietshäusern mit mehreren Parteien schon wieder Philosophie, aber wenn Du mal vor einer Briefkastenanlage mit 150 Briefkästen gestanden hast, die nach Etage und Wohnung (uns verstänlicherweise nicht nach Alphabet) sortiert ist, dann ergibt sich automatisch, dass die Sortierung sogar noch bis auf diese Ebene hinab reicht.

          Eine gute Zustellsoftware und ein guter Location Controller machen schon die halbe Qualität eines Aboservices / Zustelldienstes aus. Da übt man am besten am kleinen überschaubaren Objekt, bevor man auf die echten Auflagen losgeht ;-)

          Harzliche Grüße vom Berg
          http://bergpost.annerschbarrich.de

          Tom

          --
          Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
          Nur selber lernen macht schlau
          Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)

    2. Ich biete ja einem User die Möglichkeit nachträglich die Reihenfolge zu beinflussen. Bei einer übersichtlichen Datensatzmenge von max. 30 Einträgen ist da eine Zahl schon naheliegender. Ich habe es doch mit 1,2,3 lösen können. Ich lese halt die ID der zwei zu tauschenden Werte aus und Update diese Werte dann gegenverkehrt. Also zwei Updates, die ich mit PHP ausführe. Direkt im mySQL hab ich keine Lösung gefunden.

      Gruß Didi

      1. Hello,

        Ich biete ja einem User die Möglichkeit nachträglich die Reihenfolge zu beinflussen. Bei einer übersichtlichen Datensatzmenge von max. 30 Einträgen ist da eine Zahl schon naheliegender. Ich habe es doch mit 1,2,3 lösen können. Ich lese halt die ID der zwei zu tauschenden Werte aus und Update diese Werte dann gegenverkehrt. Also zwei Updates, die ich mit PHP ausführe. Direkt im mySQL hab ich keine Lösung gefunden.

        Das geht in SQL in einem Statment und sollte auch dringend so gelöst werden, damit man sich das LOCK auf die Tabelle spart!

        update tabelle set zahl = (if zahl = x, y, x) where zahl in (x, y);

        http://dev.mysql.com/doc/refman/5.1/en/control-flow-functions.html#function_if
        http://dev.mysql.com/doc/refman/5.1/en/comparison-operators.html#function_in

        Harzliche Grüße vom Berg
        http://bergpost.annerschbarrich.de

        Tom

        --
        Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
        Nur selber lernen macht schlau
        Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)