2009-04-01 10 views
79

J'espère que cela avait un sens, permettez-moi de préciser:SQL UPDATE SET une colonne doit être égale à une valeur dans une table liée référencée par une colonne différente?

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

QuestionID et AnswerID (il y a une table pour chaque). Donc, à cause d'un bug, il y avait un tas de QuestionIDs mis à NULL, mais le QuestionID d'un AnswerID se trouve dans le tableau Answers. Donc, si QuestionID est NULL et AnswerID est 500, si nous allons à la table Answers et que nous trouvons AnswerID 500 il y a une colonne avec le QuestionID qui aurait dû être où la valeur NULL est. Donc, fondamentalement, je veux que chaque QuestionID NULL soit égal à l'identifiant QuestionID trouvé dans le tableau Réponses sur la ligne Answer de l'AnswerID qui se trouve dans la table des trackings (même ligne que l'identifiant NULL QuestionID en cours d'écriture).

Comment est-ce que je ferais ceci?

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

Je ne sais pas comment je vais pouvoir le faire assigner le QuestionID au QuestionID du AnswerID correspondant ...

+0

MySQL et Microsoft SQL Server chaque extensions de soutien à la syntaxe SQL pour soutenir UPDATE multi-table. D'autres marques ne le font pas. Vous n'avez pas dit quelle marque de base de données vous utilisez. –

Répondre

123
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 ce que le résultat mis à jour est en cours d'exécution avant la mise à jour (même requête, juste avec une sélection):

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 est certainement seulement 1 id question associée.

+6

Je pense que cela ne fonctionne pas à ORACLE :( –

+5

Je ne sais pas pourquoi, mais cela ne fonctionne pas pour moi, cependant cela: 'mise à jour QuestionTrackings q jointure interne QuestionAnswers a sur q.AnswerID = a.AnswerID ensemble q.QuestionID = a.QuestionID; ' semble être la même requête de base dans un ordre différent une idée pourquoi – billynoah

+2

@billynoah, ORA-00971: mot-clé SET manquant dans Oracle – masT

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

J'ai travaillé sur Oracle pour moi. La réponse de @ eglasius n'a pas. – Lombas

22

Sans la mise à jour et jointure notation (pas tous les SGBD prennent en charge que), utilisez:

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) 

Souvent dans une requête comme celui-ci, vous devez qualifier la clause WHERE avec une clause EXISTS qui contient la sous-requête. Cela empêche le UPDATE de piétiner sur les lignes où il n'y a pas de correspondance (annulant généralement toutes les valeurs). Dans ce cas, étant donné qu'un identifiant de question manquant changerait la valeur NULL en NULL, cela n'a sans doute pas d'importance.

7

J'avais la même question. Voici une solution de travail similaire à celle d'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 dans la ligne 1, et rien ne doit précéder QuestionID dans la ligne 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; 
9

Je ne sais pas si vous avez exécuté dans la même problème que moi sur MySQL Workbench mais l'exécution de la requête avec le INNER JOIN après l'instruction FROM n'a pas fonctionné pour moi. Impossible d'exécuter la requête car le programme s'est plaint de l'instruction FROM.

Ainsi, afin de rendre le travail de recherche je l'ai changé pour

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

au lieu de

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

Je suppose que ma solution est la bonne syntaxe pour MySQL.

+0

Cela a fonctionné pour moi aussi sur MySQL – nads

1

Mise à jour des données 2e table dans le 1er tableau doivent INNER JOIN avant SET:

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