120 votes

SQL UPDATE SET une colonne égale à une valeur dans une table liée référencée par une colonne différente?

J'espère que ça avait du sens, permettez-moi de préciser:

Il y a un tableau de suivi des données pour un quiz où chaque ligne a..

QuestionID et AnswerID (il y a un tableau pour chaque). Donc, à cause d'un bug, il y avait un tas de QuestionIDs définie à NULL, mais le QuestionID d'une AnswerID est dans les Réponses de la table.

Donc, dire QuestionID est NULLE et AnswerID est de 500, si nous allons à la les Réponses de la table et de trouver AnswerID 500 il y a une colonne avec le QuestionID qui devrait avoir été où la valeur NULL est.

Donc, fondamentalement, je veux mettre chaque NULL QuestionID être égale à la QuestionID trouvé dans les Réponses de la table sur la Réponse ligne de la AnswerID qui est dans le relâchement de la table (même ligne que le NULL QuestionID qui est en cours d'écriture).

Comment puis-je faire?

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

Pas sûr de savoir comment je vais être capable de le faire céder le QuestionID à la QuestionID de la mise en correspondance AnswerID...

177voto

eglasius Points 26221
 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
 

Je recommande de vérifier quel est le résultat à mettre à jour avant d'exécuter la mise à jour (même requête, avec un select):

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

En particulier si chaque identifiant de réponse n'a définitivement qu'un identifiant de question associé.

32voto

Jonathan Leffler Points 299946

Sans la notation update-and-join (ce n'est pas tout le SGBD qui prend en charge cela), utilisez:

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

Souvent, dans une requête comme celle-ci, vous devez qualifier la clause WHERE avec une clause EXISTS contenant la sous-requête. Cela empêche la mise à jour de piétiner les lignes où il n'y a pas de correspondance (généralement en annulant toutes les valeurs). Dans ce cas, puisqu'un identifiant de question manquant changerait NULL en NULL, cela n'a sans doute aucune importance.

13voto

Milen A. Radev Points 20462
UPDATE
    "QuestionTrackings"
SET
    "QuestionID" = (SELECT "QuestionID" FROM "Answers" WHERE "AnswerID"="QuestionTrackings"."AnswerID")
WHERE
    "QuestionID" is NULL
AND ...

7voto

Lighting Minds Points 13

J'avais la même question. Voici une solution de travail similaire à celle de Eglasius. J'utilise postgresql.

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

Il se plaint si q a été utilisé à la place du nom de la table à la ligne 1 et que rien ne devrait précéder QuestionID à la ligne 2.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X