Domanda

Ho una tabella di record in mySql. Devo mantenere un ordine per loro come specificato dall'utente. Quindi ho aggiunto una colonna 'position'.

Quale sarebbe l'istruzione SQL per aggiornare tutti i record quando sposto un record specifico? Ho qualcosa del tipo:

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

Ma il maggiore di sarà inferiore a se il record si è spostato verso il basso. Qual è il trucco? Grazie!

È stato utile?

Soluzione

Fare questo genere di cose per es. ordini di vendita con numeri di riga gestiti dall'utente, ho trovato la soluzione migliore per gestirlo in un array nell'interfaccia BL o nell'interfaccia utente. Di solito vorranno regolare diversi record, e talvolta vorranno dire & Quot; dimenticalo & Quot ;. Quindi il modo più semplice potrebbe essere quello di aspettare fino a quando non premono il & Quot; OK & Quot; pulsante (o il tuo equivalente) e poi riscrivili tutti con l'ordinamento corrente.

Potresti anche finire per eliminare le eliminazioni, che è un altro problema che puoi gestire allo stesso modo.

Altri suggerimenti

Qualcosa del genere lo farebbe?

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 );

L'ho provato un paio di volte e sembra funzionare.

Questa è la mia opinione su questo: la mia colonna row_index ha un numero con un passo di 10 (es .: 0, 10, 20, ecc.). Quando un utente aggiorna una riga, devi sapere se va su o giù. Se devi spostare la 2a riga sulla 4a (scendendo, row_index desiderato = 30), imposta row_index su 35; altrimenti (se salendo) impostalo su 25. Imposta questo valore:

UPDATE your_table SET row_index = 35 WHERE your_id = 1234

Ora hai l'ordine corretto, ma i row_indexes sono incasinati. Per risolvere questo problema, esegui queste due query:

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

Questo aggiornerà tutte le tue righe (o quella selezionata con l'istruzione where) e imposterà la colonna row_index senza spazi vuoti (0, 10, 20, 30, ecc.). Sicuramente in questo modo si aggiunge carico alle operazioni di scrittura, ma penso che sia il modo più veloce per ottenere l'ordine durante le operazioni di lettura. Se elimini una riga, puoi semplicemente eseguire nuovamente le query sull'ordine di correzione.

Suggerirei, come minimo, di utilizzare grandi incrementi (diciamo 10000) tra gli elementi. Quindi sto solo facendo un ordine. Se devi spostare 11000 tra 9000 e 10000, basta impostarlo su 9500 e il gioco è fatto.

Questo non elimina il problema del riordino ma lo riduce notevolmente. Ad un certo punto è meglio eliminare tutte le righe e poi leggerle nell'ordine corretto. Fare aggiornamenti come stai facendo è troppo imho soggetto a errori.

Potresti prendere in considerazione l'utilizzo di un tipo di approccio di elenco collegato, con una chiave per il prossimo e forse l'elemento precedente nell'elenco, quindi devi aggiornare solo alcuni record, anziché tutti.

Interessante! Va bene, quindi non c'è una risposta facile. Pensavo mi mancasse qualcosa. Avevo pensato di mantenere un array esterno. Sembra l'idea migliore.

Forse qualcosa del genere?

$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 
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top