Vous ne pouvez pas spécifier la table cible pour la mise à jour dans la clause from
J'ai une simple table mysql:
CREATE TABLE IF NOT EXISTS `pers` (
`persID` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(35) NOT NULL,
`gehalt` int(11) NOT NULL,
`chefID` int(11) DEFAULT NULL,
PRIMARY KEY (`persID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;
INSERT INTO `pers` (`persID`, `name`, `gehalt`, `chefID`) VALUES
(1, 'blb', 1000, 3),
(2, 'as', 1000, 3),
(3, 'chef', 1040, NULL);
J'ai essayé d'exécuter des mises à jour suivantes, mais je reçois l'erreur 1093:
UPDATE pers P
SET P.gehalt = P.gehalt * 1.05
WHERE (P.chefID IS NOT NULL
OR gehalt <
(SELECT (
SELECT MAX(gehalt * 1.05)
FROM pers MA
WHERE MA.chefID = MA.chefID)
AS _pers
))
J'ai cherché l'erreur et trouvé de mysql page suivante http://dev.mysql.com/doc/refman/5.1/en/subquery-restrictions.html, mais il ne m'aide pas.
Que dois-je faire pour corriger la requête sql?
Vous devez vous connecter pour publier un commentaire.
Le problème est que MySQL, pour une stupide raison, il ne vous permet pas d'écrire des requêtes comme ceci:
Qui est, si vous êtes en train de faire un
UPDATE
/INSERT
/DELETE
sur une table, vous ne pouvez pas référencer la table dans une requête interne (vous peut toutefois faire référence à un champ à partir de cette table externe...)La solution est de remplacer l'instance de
myTable
dans la sous-requête avec(SELECT * FROM myTable)
, à l'instar de ceCela provoque apparemment les champs nécessaires pour être implicitement copié dans une table temporaire, donc c'est permis.
J'ai trouvé cette solution ici. Une note à cet article:
INNER JOIN
s, qui ne sont pas nécessaires et n'étaient pas dans la question d'origine.T
et(SELECT * FROM T)
sont complètement équivalentes. Ils sont de la même relation. Donc c'est un arbitraire, niais restriction. Plus précisément, elle est une solution pour forcer MySQL à faire quelque chose qu'il peut clairement faire, mais pour quelque raison il ne peut pas analyser dans sa plus simple forme.SET optimizer_switch = 'derived_merge=off';
🙁DELETE FROM t WHERE tableID NOT IN (SELECT viewID FROM t_view);
Aussi je recommande d'exécuterOPTIMIZE TABLE t;
par la suite pour réduire la taille de la table.Vous pouvez faire cela en trois étapes:
...
ou
CREATE TABLE
états - j'espère que l'auteur était conscient de cela. Cependant, est-ce la seule solution? Ou pouvez la requête être réécrite avec les sous-requêtes ou des jointures? Et pourquoi (pas) le faire?UPDATE Pers P
lireUPDATE pers P
?CREATE TABLE AS SELECT
donner des performances horribles?create table as select
donner des performances horribles?Dans Mysql, vous ne pouvez pas mettre à jour une table par sous-requête de la même table.
Vous pouvez séparer la requête en deux parties, ou ne
SELECT ... SET
? Je n'ai jamais entendu parler de cela.AS B
sur la deuxième référence deTABLE_A
. la réponse la plus-upvoted exemple pourrait être simplifiée en utilisantAS T
au lieu de potentiellement inefficaceFROM (SELECT * FROM myTable) AS something
, qui, fort heureusement, l'optimiseur de requête élimine généralement, mais pas toujours.Faire une table temporaire (tempP) à partir d'une sous-requête
J'ai introduit un autre nom (alias) et de donner un nouveau nom à 'persID colonne de table temporaire
SELECT ( SELECT MAX(gehalt * 1.05)..
- la premièreSELECT
ne permet pas de sélectionner toute la colonne.C'est assez simple. Par exemple, au lieu d'écrire:
vous devriez écrire
ou similaire.
L'Approche posté par BlueRaja est lent, je l'ai modifié comme
J'ai été en utilisant pour supprimer les doublons dans la table. Dans le cas où il peut aider n'importe qui avec des grandes tables
Requête D'Origine
Cela prend plus de temps:
Solution Plus Rapide
Comme référence, vous pouvez également utiliser Mysql Variables à enregistrer des résultats temporaires, par exemple:
https://dev.mysql.com/doc/refman/5.7/en/user-variables.html
Si vous essayez de lire fieldA de la tableA et l'enregistrer sur fieldB sur la même table, quand fieldc = fieldd vous pourriez vouloir considérer cette.
Code ci-dessus copie la valeur de fieldA à fieldB, lorsque la condition de champ rencontré votre condition. cela fonctionne aussi dans ADO (e.g accès )
source: me suis essayé
MariaDB a soulevé ce à partir de la version 10.3.x (à la fois pour
DELETE
etUPDATE
):DBFiddle MariaDB 10.2 - Erreur
DBFiddle MariaDB 10.3 - Succès
mise à jour de x set available_material_id = null where id not in (select id from x où additional_info = 1);