SQL: clausola WHERE su ciascun comando SET in UPDATE?
-
07-07-2019 - |
Domanda
Sto cercando di creare una query SQL in PHP per aggiornare una tabella.
È possibile avere una clausola WHERE
diversa per ogni riga interessata?
ad esempio qualcosa del tipo:
UPDATE table
SET val=X WHERE someproperty = 1,
SET val=Y WHERE someproperty = 2
etc?
Qualsiasi aiuto apprezzato. Grazie
Soluzione
Non è possibile avere più clausole WHERE per qualsiasi istruzione SQL, tuttavia è possibile utilizzare un'istruzione CASE per realizzare ciò che si sta tentando di fare. Un'altra opzione che hai è quella di eseguire più istruzioni UPDATE.
Ecco un esempio che utilizza l'istruzione CASE:
UPDATE table
SET val = (
CASE someproperty
WHEN 1 THEN X
WHEN 2 THEN Y
ELSE val
END
);
Ecco un esempio che utilizza più istruzioni UPDATE:
UPDATE table SET val=X WHERE someproperty = 1;
UPDATE table SET val=Y WHERE someproperty = 2;
Altri suggerimenti
Sì, puoi con un'istruzione CASE.
UPDATE table
SET val = CASE someproperty
WHEN 1 THEN x
WHEN 2 THEN y
....
ELSE
val
END
Ora, c'è il timore che un'istruzione CASE
sia meno leggibile rispetto a diverse istruzioni UPDATE
. C'è un argomento valido qui. Ad esempio, quando si aggiornano 1000 righe, è più semplice e più bello utilizzare diverse istruzioni UPDATE
anziché 1000 diverse condizioni in un singolo CASE
.
Tuttavia, a volte un'istruzione CASE è più appropriata. Se, ad esempio, stai aggiornando le righe in base a qualche tratto, ad esempio la natura pari o dispari del valore di un campo nella tabella, allora un'istruzione CASE
è un modo meravigliosamente conciso e gestibile per aggiornare le righe nel tabella senza dover ricorrere a un numero enorme di istruzioni UPDATE
che condividono tutte un tipo specifico di logica. Prendi questo per esempio:
UPDATE table
SET val = CASE MOD(someproperty, 2)
WHEN 0 THEN x
WHEN 1 THEN y
END
Questa espressione prende il modulo di someproperty e, quando 0 (pari), assegna il valore x a val e, quando 1 (dispari), assegna il valore y a val. Maggiore è il volume di dati che viene aggiornato da questa affermazione, più pulito è rispetto a farlo da più istruzioni UPDATE
.
In breve, le istruzioni CASE
sono talvolta leggibili / gestibili come le istruzioni UPDATE
. Tutto dipende da cosa stai cercando di fare con loro.
MODIFICA : aggiunta la clausola ELSE per essere ancora più sicura. L'OP potrebbe essere interessato all'aggiornamento solo di righe specifiche, quindi il resto dovrebbe rimanere come prima dell'aggiornamento.
EDIT : aggiunto uno scenario in cui l'istruzione CASE
è un approccio più efficace rispetto a più istruzioni UPDATE
.
No. Apporta due aggiornamenti:
UPDATE table SET val=X WHERE someproperty = 1;
UPDATE table SET val=Y WHERE someproperty = 2;
Ripensandoci, potresti usare le query secondarie o l'istruzione case ...
UPDATE table SET val= ( case when someproperty = 1 then X when someproperty = 2 then Y else val END )
Potrebbe essere necessario effettuare una query secondaria come questa:
UPDATE table t1 SET val = ( select CASE when someproperty = 1 then X when someproperty = 2 then Y ELSE val END from table t2 where t1.primarykey = t2.primary key )
UPDATE TABLE
SET VAL CASE SOMEPROPERTY WHEN 1 THEN X WHEN 2 THEN Y END
Un modo compatto e facilmente scalabile:
UPDATE table1 SET val=ELT(FIND_IN_SET(someproperty, '1, 2'), X, Y);
effettua la query in questo modo:
$condition = array(1, 2);
$newvals = array('X', 'Y');
$query = "UPDATE table1 SET val=ELT(FIND_IN_SET(someproperty, '". implode(',', $condition). "', ". implode(', ', $newvals). ")";
Usa preparare la query per evitare errori di sintassi SQL se gestisci i valori di stringa.