web-dev-qa-db-fra.com

MISE À JOUR SQL avec sous-requête faisant référence à la même table dans MySQL

J'essaie de mettre à jour la valeur d'une colonne dans un tas de lignes dans une table en utilisant UPDATE. Le problème est que je dois utiliser une sous-requête pour dériver la valeur de cette colonne, et cela dépend de la même table. Voici la requête:

UPDATE user_account student
SET student.student_education_facility_id = (
   SELECT teacher.education_facility_id
   FROM user_account teacher
   WHERE teacher.user_account_id = student.teacher_id AND teacher.user_type = 'ROLE_TEACHER'
)
WHERE student.user_type = 'ROLE_STUDENT';

Normalement, si l'enseignant et l'élève étaient dans 2 tables différentes, mysql ne se plaindrait pas. Mais comme ils utilisent tous les deux la même table, mysql génère cette erreur à la place:

ERREUR 1093 (HY000): Vous ne pouvez pas spécifier la table cible 'étudiant' pour la mise à jour dans la clause FROM

Existe-t-il un moyen de forcer mysql à faire la mise à jour? Je suis sûr à 100% que la clause from ne sera pas affectée lorsque les lignes seront mises à jour.

Sinon, existe-t-il un autre moyen d'écrire cette mise à jour SQL pour obtenir le même effet?

Merci!

EDIT: Je pense que je l'ai fait fonctionner:

UPDATE user_account student
LEFT JOIN user_account teacher ON teacher.user_account_id = student.teacher_id
SET student.student_education_facility_id = teacher.education_facility_id
WHERE student.user_type = 'ROLE_STUDENT';
40
egervari

Quelques références pour vous http://dev.mysql.com/doc/refman/5.0/en/update.html

UPDATE user_account student 
INNER JOIN user_account teacher ON
   teacher.user_account_id = student.teacher_id 
   AND teacher.user_type = 'ROLE_TEACHER'
SET student.student_education_facility_id = teacher.education_facility_id
45
John Hartsock

Exemple abstrait avec des noms de table et de colonne plus clairs:

UPDATE tableName t1
INNER JOIN tableName t2 ON t2.ref_column = t1.ref_column
SET t1.column_to_update = t2.column_desired_value

Comme suggéré par @Nico

J'espère que cela aidera quelqu'un.

20
Simon Arnold
UPDATE user_account 
SET (student_education_facility_id) = ( 
    SELECT teacher.education_facility_id
    FROM user_account teacher
    WHERE teacher.user_account_id = teacher_id
    AND teacher.user_type = 'ROLE_TEACHER'
)
WHERE user_type = 'ROLE_STUDENT'

Ci-dessus, l'exemple de requête de mise à jour ...

Vous pouvez écrire une sous-requête avec une instruction SQL de mise à jour, vous n'avez pas besoin de donner un nom d'alias pour cette table. donner un nom d'alias à la sous-table de requête. J'ai essayé et ça marche bien pour moi ....

5
Ricky Patel
UPDATE user_account student

SET (student.student_education_facility_id) = (

   SELECT teacher.education_facility_id

   FROM user_account teacher

   WHERE teacher.user_account_id = student.teacher_id AND teacher.user_type = 'ROLE_TEACHER'

)

WHERE student.user_type = 'ROLE_STUDENT';
2
Sin2

J'en avais besoin pour SQL Server. C'est ici:

UPDATE user_account 
SET student_education_facility_id = cnt.education_facility_id
from  (
   SELECT user_account_id,education_facility_id
   FROM user_account 
   WHERE user_type = 'ROLE_TEACHER'
) as cnt
WHERE user_account.user_type = 'ROLE_STUDENT' and cnt.user_account_id = user_account.teacher_id

Je pense que cela fonctionne avec d'autres SGBDR (veuillez confirmer). J'aime la syntaxe car elle est extensible.

Le format dont j'avais besoin était en fait:

UPDATE table1 
SET f1 = cnt.computed_column
from  (
   SELECT id,computed_column --can be any complex subquery
   FROM table1
) as cnt
WHERE cnt.id = table1.id
2
Mahmoodvcs