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';
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
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.
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 ....
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';
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