SQL UPDATE IMPOSTARE una colonna come uguale a un valore in una tabella correlata a cui fa riferimento una colonna diversa?


112

Spero che abbia senso, lasciami elaborare:

C'è una tabella di dati di monitoraggio per un programma di quiz in cui ogni riga ha ..

QuestionID e AnswerID (c'è una tabella per ciascuno). Quindi, a causa di un bug, c'erano un gruppo di QuestionID impostati su NULL, ma il QuestionID di un AnswerID correlato è nella tabella Risposte.

Quindi supponiamo che QuestionID sia NULL e AnswerID sia 500, se andiamo alla tabella Answers e troviamo AnswerID 500 c'è una colonna con QuestionID che avrebbe dovuto essere dove si trova il valore NULL.

Quindi, in pratica, voglio impostare ogni QuestionID NULL in modo che sia uguale al QuestionID trovato nella tabella Risposte sulla riga Risposta dell'ID risposta che si trova nella tabella di tracciamento (stessa riga del QuestionID NULL che viene scritto).

Come lo farei?

UPDATE QuestionTrackings
SET QuestionID = (need some select query that will get the QuestionID from the AnswerID in this row)
WHERE QuestionID is NULL AND ... ?

Non sono sicuro di come potrò fare in modo che assegni il QuestionID al QuestionID dal corrispondente AnswerID ...


MySQL e Microsoft SQL Server supportano ciascuno le estensioni alla sintassi SQL per supportare l'UPDATE su più tabelle. Altre marche no. Non hai detto quale marca di database stai utilizzando.
Bill Karwin

Risposte:


171
update q
set q.QuestionID = a.QuestionID
from QuestionTrackings q
inner join QuestionAnswers a
on q.AnswerID = a.AnswerID
where q.QuestionID is null -- and other conditions you might want

Consiglio di controllare qual è il set di risultati da aggiornare prima di eseguire l'aggiornamento (stessa query, solo con una selezione):

select *
from QuestionTrackings q
inner join QuestionAnswers a
on q.AnswerID = a.AnswerID
where q.QuestionID is null -- and other conditions you might want

In particolare se ogni ID risposta ha sicuramente solo 1 ID domanda associato.


7
Non sono sicuro del perché, ma questo non funziona per me, tuttavia funziona: update QuestionTrackings q inner join QuestionAnswers a on q.AnswerID = a.AnswerID set q.QuestionID = a.QuestionID; sembra essere la stessa query di base in un ordine diverso. qualche idea del perché?
billynoah

2
@billynoah, ORA-00971: parola chiave SET mancante in Oracle
masT

2
Hai un problema con una situazione simile in PhpMyAdmin su MySQL. Nel mio caso, le colonne di origine e di destinazione sono nella stessa tabella, ma la selezione dei record si basa sull'altra tabella. La versione "SELECT" della query funziona, ma l'istruzione UPDTATE genera un errore di sintassi in "FROM"
2NinerRomeo

3
Ho superato il mio problema eliminando il "FROM" Sembrava più simile a questo:UPDATE table1 NATURAL JOIN table2 SET table1.col1 = table1.col2 WHERE table2.col3 ="condition"
2NinerRomeo

"q" da "aggiorna q" nella risposta è un parametro di query letterale o è solo la tua scorciatoia per il nome di una tabella?
Shawn

28

Senza la notazione update-and-join (non tutti i DBMS lo supportano), usa:

UPDATE QuestionTrackings
   SET QuestionID = (SELECT QuestionID
                        FROM AnswerTrackings
                        WHERE AnswerTrackings.AnswerID = QuestionTrackings.AnswerID)
   WHERE QuestionID IS NULL
     AND EXISTS(SELECT QuestionID
                        FROM AnswerTrackings
                        WHERE AnswerTrackings.AnswerID = QuestionTrackings.AnswerID)

Spesso in una query come questa, è necessario qualificare la clausola WHERE con una clausola EXISTS che contiene la sottoquery. Ciò impedisce all'UPDATE di calpestare le righe in cui non c'è corrispondenza (di solito annullando tutti i valori). In questo caso, poiché un ID domanda mancante cambierebbe il NULL in NULL, probabilmente non ha importanza.


Questo metodo ha funzionato per me su Oracle 12c (dove il metodo update-join non è riuscito).
shwartz

16

Non so se hai riscontrato lo stesso problema di me su MySQL Workbench, ma l'esecuzione della query con INNER JOINl' FROMistruzione after non ha funzionato per me. Non sono stato in grado di eseguire la query perché il programma si è lamentato FROMdell'istruzione.

Quindi, per far funzionare la query, l'ho modificata in

UPDATE table1 INNER JOIN table2 on table1.column1 = table2.column1
SET table1.column2 = table2.column4
WHERE table1.column3 = 'randomCondition';

invece di

UPDATE a
FROM table1 a INNER JOIN table2 b on a.column1 = b.column1
SET a.column2 = b.column4
WHERE a.column3 = 'randomCondition';

Immagino che la mia soluzione sia la sintassi giusta per MySQL.


Sì, sembra che per Mysql, JOIN sia considerato parte della parte "table_references" di una query. Iscrizione a MySQL
AWP

12
UPDATE
    "QuestionTrackings"
SET
    "QuestionID" = (SELECT "QuestionID" FROM "Answers" WHERE "AnswerID"="QuestionTrackings"."AnswerID")
WHERE
    "QuestionID" is NULL
AND ...

1
Ha lavorato su Oracle per me. La risposta di @ eglasius no.
Lombas

7

Stavo facendo la stessa domanda. Ecco una soluzione funzionante simile a quella di eglasius. Sto usando postgresql.

UPDATE QuestionTrackings
SET QuestionID = a.QuestionID
FROM QuestionTrackings q, QuestionAnswers a
WHERE q.QuestionID IS NULL

Si lamenta se q è stato utilizzato al posto del nome della tabella nella riga 1 e nulla dovrebbe precedere QuestionID nella riga 2.


3
 select p.post_title,m.meta_value sale_price ,n.meta_value   regular_price
    from  wp_postmeta m 
    inner join wp_postmeta n
      on m.post_id  = n.post_id
    inner join wp_posts p
      ON m.post_id=p.id 
    and m.meta_key = '_sale_price'
    and  n.meta_key = '_regular_price'
     AND p.post_type = 'product';



 update  wp_postmeta m 
inner join wp_postmeta n
  on m.post_id  = n.post_id
inner join wp_posts p
  ON m.post_id=p.id 
and m.meta_key = '_sale_price'
and  n.meta_key = '_regular_price'
 AND p.post_type = 'product'
 set m.meta_value = n.meta_value;

3

Per Mysql puoi usare questa query

AGGIORNA tabella1 a, tabella2 b SET a.coloumn = b.coloumn WHERE a.id = b.id


1

Aggiornare i dati della seconda tabella nella prima tabella deve essere Inner join prima di SET:

`UPDATE `table1` INNER JOIN `table2` ON `table2`.`id`=`table1`.`id` SET `table1`.`name`=`table2`.`name`, `table1`.`template`=`table2`.`template`;

1

sotto funziona per mysql

update table1 INNER JOIN table2 on table1.col1 =  table2.col1
set table1.col1 =  table2.col2

0

Penso che dovrebbe funzionare.

UPDATE QuestionTrackings
SET QuestionID = (SELECT QuestionID
                  FROM AnswerTrackings
                  WHERE AnswerTrackings.AnswerID = QuestionTrackings.AnswerID)
WHERE QuestionID IS NULL
AND AnswerID IS NOT NULL;
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.