MySQL-Fehler 1054, (angeblich!) fehlende Spalte
bearbeitet von
Hallo
Ich habe ein Problem mit einem Query, bei dem moniert wird, dass ich eine *angeblich* nicht existierende Spalte benutze. Ich habe eine MySQL-Datebnak uaf meinem Webspace mit der Serverversion 8.0.41 und darin folgende Tabelle.
~~~ sql
CREATE TABLE `tbl_uploads` (
`id` int UNSIGNED NOT NULL AUTO_INCREMENT,
`uploader` int UNSIGNED DEFAULT NULL,
`filename` varchar(64) COLLATE utf8mb4_bin DEFAULT NULL,
`tstamp` datetime DEFAULT NULL,
ADD PRIMARY KEY (`id`),
ADD KEY `fname` (`filename`) USING BTREE;
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
~~~
Ich würde gerne die Definition der Spalte `filename` mit einem PHP-Skript mit einem per `mysqli_query` ausgeführten Query ändern. Zuvor möchte ich mit einer Löschabfrage sicherstellen, dass es keine zwei (oder mehr) Einträge mit identischen Werten in dieser Spalte gibt. Dazu habe ich mich belesen und habe einen Query mit Subquery für die Angabe der zu löschenden Werte gefunden und angepasst.
~~~ sql
DELETE FROM `tbl_uploads`
WHERE `id` IN (
SELECT `temp_id` FROM (
SELECT `t1`.`id` AS `temp_id` FROM `tbl_uploads` as `t1`
INNER JOIN `tbl_uploads` as `t2`
ON `t1`.`id` > `t2`.`id` AND `t1`.`filename` = `t2`.`filename`
) AS c
)
~~~
Der Part `SELECT `temp_id` FROM (…) AS c` um den eigentlichen Subquery ist nötig, da sonst der Optimiser von MySQL querschlägt. *Dieser Query funktioniert auf der Zieldatenbank* auf meinem Webspace, wenn ich ihn per phpMyAdmin ausführe. Wenn ich ihn jedoch über das PHP-Skript ausführe, wird mir eine nicht existente Spalte `t1.filename` gemeldet.
~~~
Error in line 3722: 1054, Unknown column 't1.filename' in 'on clause'
~~~
Um das Problem einzugrenzen, habe ich den Query Zeichen für Zeichen auf etwaige Schreibfehler geprüft. Ich habe nix gefunden. Danach habe ich mit der Struktur der Abfrage herumexperimentiert. Das `DELETE` habe ich mit `SELECT *` ersetzt.
~~~ sql
SELECT * FROM `tbl_uploads`
WHERE `id` IN (
SELECT `temp_id` FROM (
SELECT `t1`.`id` AS `temp_id` FROM `tbl_uploads` as `t1`
INNER JOIN `tbl_uploads` as `t2`
ON `t1`.`id` > `t2`.`id` AND `t1`.`filename` = `t2`.`filename`
) AS c
)
~~~
Egal, ob in der dazugehörigen Tabelle Doubletten existierten oder nicht, im phpMyAdmin funktioniert der Query und gibt bei Doubletten diese auch aus beziehungsweise löscht sie.
Gliedere ich die Bedingungen aus dem ON des JOINs in eine WHERE-Klausel aus, funktioniert der Query in phpMyAdmin sowohl mit `SELECT *`als auch mit `DELETE` immer noch, aber im Skript in beiden Versionen nach wie vor nicht. Die Fehlermeldung bezieht sich in jedem Testszenario auf `t1.filename`, egal ob in der 'on clause' oder in der 'where clause'.
~~~ sql
/* Vergleich von 'filename' in ON, Vergleich der 'id' im WHERE */
SELECT * FROM `tbl_uploads`
WHERE `id` IN (
SELECT `temp_id` FROM (
SELECT `t1`.`id` AS `temp_id` FROM `tbl_uploads` as `t1`
INNER JOIN `tbl_uploads` as `t2`
ON `t1`.`filename` = `t2`.`filename`
WHERE `t1`.`id` > `t2`.`id`
) AS c
)
Error in line 3722: 1054, Unknown column 't1.filename' in 'on clause'
/* Vergleich der 'id' in ON, Vergleich von 'filename' im WHERE */
SELECT * FROM `tbl_uploads`
WHERE `id` IN (
SELECT `temp_id` FROM (
SELECT `t1`.`id` AS `temp_id` FROM `tbl_uploads` as `t1`
INNER JOIN `tbl_uploads` as `t2`
ON `t1`.`id` > `t2`.`id`
WHERE `t1`.`filename` = `t2`.`filename`
) AS c
)
Error in line 3723: 1054, Unknown column 't1.filename' in 'where clause'
~~~
Was zum Henker übersehe ich? Ich weiß nicht, ob ich einem generellen Denkfehler unterliege oder ob ich „nur“ betriebsblind eine Kleinigkeit übersehe.
„Witz“ am Rande: auf einem anderen DB-Server mit MySQL 5.7 statt 8.0 beim selben Hoster funktionierte die Abfrage auch mit dem selben PHP-Skript. Eine irgendwie zu neue Syntax dürfte also nicht der Grund für das Scheitern sein. Leider gibt die MySQL-Doku die Version, ab der eine bestimmte Syntax unterstützt wird, nur schwer oder gar nicht her, also kann ich mir dessen auch nur nicht sicher sein.
In dieser Hinsicht ist die PHP-Doku um Längen besser (Funktion `bla_blubb_trallala` => PHP ab 4.0.17, PHP 5.x, PHP 7.x, PHP 8.x).
Tschö, Auge
--
„Habe ich mir das nur eingebildet, oder kann der kleine Hund wirklich sprechen?“ fragte Schnapper.
„Er behauptet, nicht dazu imstande zu sein“ erwiderte Victor.
Schnapper zögerte (…) „Nun …“ sagte er schließlich, „ich schätze, er muss es am besten wissen.“
Terry Prattchett, Voll im Bilde