2013-07-02 12 views
11

Supponiamo un tavolo fruits che assomiglia a questo:Mysql: dati Swap per i diversi filari

------------------------------------------ 
| id | name | color | calories | 
------------------------------------------ 
| 1 | apple  | red  | 20  | 
| 2 | orange  | orange | 10  | 
| 3 | grapes  | green  | 5  | 
| 4 | bananas | yellow | 15  | 
| 5 | plum  | purple | 25  | 
------------------------------------------ 

Come posso di swap i valori di una riga, con un altro, lasciando intatto il numero di identificazione?

Esempio:

SWAP ROW WITH ID "5" WITH ROW WITH ID "2" 

Risultato:

------------------------------------------ 
| id | name | color | calories | 
------------------------------------------ 
| 1 | apple  | red  | 20  | 
| 2 | plum  | purple | 25  | 
| 3 | grapes  | green  | 5  | 
| 4 | bananas | yellow | 15  | 
| 5 | orange  | orange | 10  | 
------------------------------------------ 

Si noti che tutti i valori sono intatte, tranne per l'id. Ho bisogno di fare questo con una lista di valori molto ampia, quindi ho bisogno di un one-liner, o al massimo, qualcosa che non richieda la creazione di tabelle temporanee, e cose del genere.

Nota: id è unico

Grazie

+1

come qualsiasi altra operazione di scambio in quasi tutti gli altri linguaggi di programmazione. copia i dati del record n. 1 nella memoria temporanea, copia i dati del record n. 2 nella registrazione n. 1. quindi copia i dati dalla memoria temporanea nella registrazione n. 2. Non esiste un'operazione di 'swap' incorporata in SQL per fare ciò che vuoi in una singola query ordinata. –

+1

o scrivi uno script che faccia la stessa cosa (come il commento di @MarcB) – Sai

+0

La memoria temporanea potrebbe essere una nuova riga nella tabella? Devo assicurarmi che la riga sia cancellata quando l'operazione di copia è terminata, sebbene –

risposta

4

È potrebbe utilizzare un disuguaglianza iscriverti per allineare le righe che si desidera scambiare:

update fruit a 
inner join fruit b on a.id <> b.id 
    set a.color = b.color, 
     a.name = b.name, 
     a.calories = b.calories 
where a.id in (2,5) and b.id in (2,5) 

http://sqlfiddle.com/#!2/18b9c/1

+0

Man ... Sei un genio !! Molto utile, grazie! –

4

Dal ID è unico, è difficile solo scambiare gli ID, è più facile per scambiare i contenuti della colonna. Una query come questo potrebbe essere quello che ti serve:

UPDATE 
    yourtable t1 INNER JOIN yourtable t2 
    ON (t1.id, t2.id) IN ((1,5),(5,1)) 
SET 
    t1.color = t2.color, 
    t1.name = t2.name, 
    t1.calories = t2.calories 

Si prega di vedere il violino here.

+0

è un ottimo modo per farlo :) – Sai

+0

@fthiella beautiful :) –

0

Ecco un modo per memorizzare i valori temporaneamente senza utilizzare una tabella temporanea o di una riga fittizia nella tabella frutta:

SELECT name, color, calories FROM fruit WHERE id = 2 INTO @name, @color, @calories; 

UPDATE fruit AS f1, fruit AS f2 
SET 
f1.name = f2.name, f2.name = @name, 
f1.color = f2.color, f2.color = @color, 
f1.calories = f2.calories, f2.calories = @calories 
WHERE (f1.id, f2.id) = (2, 5); 

Ecco un'altra soluzione che utilizza un valore id fittizio:

UPDATE fruit SET id = 0 WHERE id = 5; 
UPDATE fruit SET id = 5 WHERE id = 2; 
UPDATE fruit SET id = 2 WHERE id = 0; 
0

Se le operazioni si basano su ID, e si desidera scambiare intere righe, un modo elegante per scambiare ID univoci è quello di iniziare a numerazione da 1, e utilizzare 0 come temporanea valore.

Un altro modo per eseguire questa operazione consiste nell'utilizzare una colonna senza segno e utilizzare un valore designato (ovvero: -1) per il temporaneo. Non consiglierei veramente quest'ultimo, dato che siamo effettivamente sprecando spazio con questo metodo. Vedi http://dev.mysql.com/doc/refman/5.0/en/numeric-type-overview.html per maggiori dettagli.