Ich habe eine einfache MySQL-Tabelle:
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);
Ich habe versucht, das folgende Update auszuführen, erhalte jedoch nur den Fehler 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
))
Ich habe nach dem Fehler gesucht und auf MySQL die folgende Seite gefunden: http://dev.mysql.com/doc/refman/5.1/en/subquery-restrictions.html , aber es hilft mir nicht.
Was soll ich tun, um die SQL-Abfrage zu korrigieren?
sql
mysql
mysql-error-1093
CSchulz
quelle
quelle
Antworten:
Das Problem ist, dass Sie mit MySQL aus irgendeinem Grund keine Abfragen wie diese schreiben können:
Das heißt, wenn Sie eine
UPDATE
/INSERT
/DELETE
für eine Tabelle ausführen, können Sie diese Tabelle nicht in einer inneren Abfrage referenzieren (Sie können jedoch auf ein Feld aus dieser äußeren Tabelle verweisen ...)Die Lösung besteht darin, die Instanz von
myTable
in der Unterabfrage(SELECT * FROM myTable)
wie folgt zu ersetzenDies führt anscheinend dazu, dass die erforderlichen Felder implizit in eine temporäre Tabelle kopiert werden, sodass dies zulässig ist.
Ich habe diese Lösung hier gefunden . Ein Hinweis aus diesem Artikel:
quelle
T
und(SELECT * FROM T)
sind völlig gleichwertig. Sie sind die gleiche Beziehung. Daher ist dies eine willkürliche, inane Einschränkung. Insbesondere ist es eine Problemumgehung, MySQL dazu zu zwingen, etwas zu tun, was es eindeutig kann, aber aus irgendeinem Grund kann es nicht in seiner einfacheren Form analysiert werden.DELETE FROM t WHERE tableID NOT IN (SELECT viewID FROM t_view);
Ich empfehle auch,OPTIMIZE TABLE t;
danach zu laufen , um die Größe der Tabelle zu reduzieren.Sie können dies in drei Schritten durchführen:
...
oder
quelle
CREATE TABLE
Anweisungen umgeschrieben werden - ich hoffe, der Autor war sich dessen bewusst. Ist dies jedoch die einzige Lösung? Oder kann die Abfrage mit Unterabfragen oder Verknüpfungen neu geschrieben werden? Und warum (nicht) das tun?UPDATE Pers P
lesenUPDATE pers P
?CREATE TABLE AS SELECT
schreckliche Leistung?In MySQL können Sie eine Tabelle nicht aktualisieren, indem Sie dieselbe Tabelle abfragen.
Sie können die Abfrage in zwei Teile trennen oder tun
quelle
SELECT ... SET
? Ich habe noch nie davon gehört.AS B
beim zweiten Verweis auf verwendet wirdTABLE_A
. Die Antwort im am besten bewerteten Beispiel könnte vereinfacht werden, indemAS T
anstelle des potenziell ineffizienten verwendet wirdFROM (SELECT * FROM myTable) AS something
, was glücklicherweise vom Abfrageoptimierer normalerweise eliminiert wird, dies jedoch möglicherweise nicht immer tut.Erstellen Sie aus einer Unterabfrage eine temporäre Tabelle (tempP)
Ich habe einen separaten Namen (Alias) eingeführt und der Spalte 'persID' für die temporäre Tabelle einen neuen Namen gegeben
quelle
SELECT ( SELECT MAX(gehalt * 1.05)..
- Der ersteSELECT
wählt keine Spalte aus.Es ist ganz einfach. Zum Beispiel anstatt zu schreiben:
du solltest schreiben
o.ä.
quelle
Der von BlueRaja veröffentlichte Ansatz ist langsam. Ich habe ihn geändert, als ich Duplikate aus der Tabelle löschte. Falls es jemandem mit großen Tabellen hilft Originalabfrage
Das braucht mehr Zeit:
Schnellere Lösung
quelle
Als Referenz können Sie auch MySQL-Variablen verwenden, um temporäre Ergebnisse zu speichern, z.
https://dev.mysql.com/doc/refman/5.7/en/user-variables.html
quelle
Wenn Sie versuchen, FeldA aus TabelleA zu lesen und es in FeldB in derselben Tabelle zu speichern, sollten Sie dies bei fieldc = fieldd berücksichtigen.
Der obige Code kopiert den Wert von FeldA nach FeldB, wenn das Bedingungsfeld Ihre Bedingung erfüllt. Dies funktioniert auch in ADO (zB Zugriff)
Quelle: habe es selbst versucht
quelle
MariaDB hat dies ab 10.3.x aufgehoben (sowohl für
DELETE
als auchUPDATE
):DBFiddle MariaDB 10.2 - Fehler
DBFiddle MariaDB 10.3 - Erfolg
quelle
Andere Problemumgehungen umfassen die Verwendung von SELECT DISTINCT oder LIMIT in der Unterabfrage, obwohl diese in ihrer Auswirkung auf die Materialisierung nicht so explizit sind. das hat bei mir funktioniert
wie in MySql Doc erwähnt
quelle
MySQL erlaubt es nicht, aus einer Tabelle auszuwählen und gleichzeitig in derselben Tabelle zu aktualisieren. Aber es gibt immer eine Problemumgehung :)
Das funktioniert nicht >>>>
Aber das funktioniert >>>>
quelle