Frage

Ich habe eine Tabelle von Datensätzen in mySql. Ich brauche einen Auftrag für sie zu halten, wie vom Benutzer angegeben. Also habe ich eine ‚Position‘ Spalt hinzugefügt.

Was wäre die SQL-Anweisung alle Datensätze zu aktualisieren, wenn ich einen bestimmten Datensatz bewegen? Ich habe so etwas wie:

UPDATE items SET position = '2' WHERE id ='4';
UPDATE items SET position = position+1 WHERE position >= '2' AND id != '4';

Aber die größer ist als wird ein kleiner sein, als wenn der Datensatz nach unten bewegt. Was ist der Trick? Dank!

War es hilfreich?

Lösung

Doing diese Art der Sache für z.B. Kundenaufträge mit Zeilennummern vom Benutzer gepflegt, habe ich es am besten zu handhaben es in einem Array in den BL oder UI gefunden. Normalerweise wollen sie mehrere Datensätze einzustellen, und manchmal sagen wollen „vergessen“. So könnte die einfachste sein, nur zu warten, bis sie auf die „OK“ Button drücken (oder Sie äquivalent) und dann schreiben sie alle mit aktueller Bestellung zurück.

Sie können am Ende mit Deletionen zu tun, auch, und das ist ein weiteres Problem, das Sie die gleiche Art und Weise umgehen können.

Andere Tipps

wäre so etwas wie dies tun?

UPDATE items 
SET position = CASE position 
  WHEN $oldpos THEN $newpos 
  ELSE position + SIGN($oldpos-$newpos)
 END
WHERE position BETWEEN LEAST( $newpos, $oldpos ) 
                AND GREATEST( $newpos, $oldpos );

Ich habe es getestet ein paar Mal, und es scheint zu funktionieren.

Das ist meine Meinung dazu: meine row_index Spalte hat die Nummer mit einem Schritt von 10 (zB .: 0, 10, 20, ecc.). Wenn ein Benutzer aktualisiert eines der Zeile, die Sie müssen wissen, ob es nach oben oder unten gehen. Wenn Sie die zweite Reihe zum vierten bewegen (nach unten geht, gewünschte row_index = 30), stellen Sie den row_index bis 35; sonst (wenn hinauf) setzen Sie ihn auf 25. Setzen Sie diesen Wert:

UPDATE your_table SET row_index = 35 WHERE your_id = 1234

Jetzt haben Sie die richtige Reihenfolge, aber die row_indexes sind durcheinander. Um dies zu beheben, führen Sie diese zwei Abfragen:

SET @pos:=-10;
UPDATE your_table SET row_index = @pos:=@pos+10 WHERE ...

Das wird alle Ihre Zeilen aktualisieren (oder die, die Sie mit der where-Anweisung wählen) und stellen Sie die row_index Spalte ohne Lücken (0, 10, 20, 30, ecc.). Sicherlich diese Art und Weise fügt Belastung der Schreiboperationen, aber ich denke, es ist der schnellste Weg, den Auftrag während der Lesevorgänge zu erhalten. Wenn Sie eine Zeile löschen können Sie einfach erneut die Befestigungs um Abfragen ausführen.

Ich würde vorschlagen, auf ein Minimum, großen Schritten unter Verwendung von (sagen wir 10000) zwischen den einzelnen Posten. Dann tun gerade eine Bestellung durch. Wenn Sie 11000 zwischen 9000 und 10000 bewegen müssen dann setzt es nur 9500 und fertig.

Das ist nicht das Problem der Neuordnungs beseitigen, sondern es reduziert sie stark. Irgendwann bist du besser dran dann alle Zeilen löschen sie mit der richtigen Reihenfolge readding. Doing Updates wie Sie tun Fehler einfach zu anfällig imho.

Sie sollten erwägen eine verkettete Liste Art von Ansatz, mit einem Schlüssel zum anderen, und vielleicht dem vorherigen Element in der Liste, dann müssen Sie nur ein paar Datensätze aktualisieren, statt sie alle.

Interessant! Okay, so gibt es keine einfache Antwort. Ich dachte, dass ich gerade etwas fehlt. Ich hatte gedacht, über ein externes Array beibehalten wird. Das klingt wie die beste Idee.

Vielleicht so etwas wie das?

$item_id = $_GET['item_id']; 
$position = $_GET['new_position']; 
$old_position = $_GET['old_position'];

if($new_position < $old_position) {
    SQL: UPDATE items SET position = position+1 WHERE position >= $new_position AND position < $old_position  
} else {  
SQL: UPDATE items SET position = position-1 WHERE position <= $new_position AND position > $old_position
}  

SQL: UPDATE items SET position = $new_position WHERE item_id = $item_id 
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top