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 la mise à jour suivante, mais je n'obtiens que 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 recherché l'erreur et trouvé à partir de la page suivante de mysql http://dev.mysql.com/doc/refman/5.1/en/subquery-restrictions.html , mais cela ne m'aide pas.
Que dois-je faire pour corriger la requête SQL?
sql
mysql
mysql-error-1093
CSchulz
la source
la source
Réponses:
Le problème est que MySQL, pour une raison quelconque, ne vous permet pas d'écrire des requêtes comme celle-ci:
Autrement dit, si vous faites un
UPDATE
/INSERT
/DELETE
sur une table, vous ne pouvez pas référencer cette table dans une requête interne (vous pouvez cependant référencer un champ de cette table externe ...)La solution consiste à remplacer l'instance de
myTable
dans la sous-requête par(SELECT * FROM myTable)
, comme ceciCela provoque apparemment la copie implicite des champs nécessaires dans une table temporaire, donc c'est autorisé.
J'ai trouvé cette solution ici . Une note de cet article:
la source
T
et(SELECT * FROM T)
sont complètement équivalents. Ils sont la même relation. C'est donc une restriction arbitraire et stupide. Plus précisément, c'est une solution de contournement pour contraindre MySQL à faire quelque chose qu'il peut clairement faire, mais pour une raison quelconque, il ne peut pas analyser sous sa forme plus simple.DELETE FROM t WHERE tableID NOT IN (SELECT viewID FROM t_view);
Je recommande également de courirOPTIMIZE TABLE t;
après pour réduire la taille de la table.Vous pouvez le faire en trois étapes:
...
ou
la source
CREATE TABLE
déclarations - j'espère que l'auteur en était conscient. Mais est-ce la seule solution? Ou la requête peut-elle être réécrite avec des sous-requêtes ou des jointures? Et pourquoi (pas) faire ça?UPDATE Pers P
lireUPDATE pers P
?CREATE TABLE AS SELECT
donne pas des performances horribles?Dans Mysql, vous ne pouvez pas mettre à jour une table en sous-interrogeant la même table.
Vous pouvez séparer la requête en deux parties, ou faire
la source
SELECT ... SET
? Je n'en ai jamais entendu parler.AS B
la deuxième référence àTABLE_A
. la réponse dans l'exemple le plus voté pourrait être simplifiée en utilisantAS T
au lieu de potentiellement inefficaceFROM (SELECT * FROM myTable) AS something
, ce qui heureusement l'optimiseur de requête élimine généralement mais ne le fait pas toujours.Créer une table temporaire (tempP) à partir d'une sous-requête
J'ai introduit un nom séparé (alias) et donne un nouveau nom à la colonne 'persID' pour la table temporaire
la source
SELECT ( SELECT MAX(gehalt * 1.05)..
- le premierSELECT
ne sélectionne aucune colonne.C'est assez simple. Par exemple, au lieu d'écrire:
tu devrais écrire
ou similaire.
la source
L'approche publiée par BlueRaja est lente, je l'ai modifiée car j'utilisais pour supprimer les doublons du tableau. Au cas où cela aiderait quiconque avec de grandes tables Original Query
Cela prend plus de temps:
Solution plus rapide
la source
Tout comme référence, vous pouvez également utiliser les variables Mysql pour enregistrer des résultats temporaires, par exemple:
https://dev.mysql.com/doc/refman/5.7/en/user-variables.html
la source
Si vous essayez de lire fieldA à partir de tableA et de l'enregistrer sur fieldB sur la même table, lorsque fieldc = fieldd vous voudrez peut-être considérer cela.
Le code ci-dessus copie la valeur de fieldA vers fieldB lorsque condition-field a rencontré votre condition. cela fonctionne également dans ADO (par exemple accès)
source: moi-même essayé
la source
MariaDB a levé cela à partir de 10.3.x (pour
DELETE
etUPDATE
):DBFiddle MariaDB 10.2 - Erreur
DBFiddle MariaDB 10.3 - Succès
la source
D'autres solutions de contournement incluent l'utilisation de SELECT DISTINCT ou LIMIT dans la sous-requête, bien que leur effet sur la matérialisation ne soit pas aussi explicite. cela a fonctionné pour moi
comme mentionné dans MySql Doc
la source
MySQL ne permet pas de sélectionner dans une table et de mettre à jour dans la même table en même temps. Mais il y a toujours une solution :)
Cela ne fonctionne pas >>>>
Mais cela fonctionne >>>>
la source