Die Abfrage, die ich ausführe, lautet wie folgt, es wird jedoch dieser Fehler angezeigt:
# 1054 - Unbekannte Spalte 'Guaranteed_postcode' in 'IN/ALL/ANY-Unterabfrage'
SELECT `users`.`first_name`, `users`.`last_name`, `users`.`email`,
SUBSTRING(`locations`.`raw`,-6,4) AS `guaranteed_postcode`
FROM `users` LEFT OUTER JOIN `locations`
ON `users`.`id` = `locations`.`user_id`
WHERE `guaranteed_postcode` NOT IN #this is where the fake col is being used
(
SELECT `postcode` FROM `postcodes` WHERE `region` IN
(
'australia'
)
)
Meine Frage lautet: Warum kann ich in der where-Klausel derselben DB-Abfrage keine gefälschte Spalte verwenden?
Sie können Spaltenaliase nur in GROUP BY-, ORDER BY- oder HAVING-Klauseln verwenden.
In Standard-SQL können Sie in einer WHERE-Klausel nicht auf einen Spaltenalias verweisen. Diese Einschränkung wird auferlegt, da bei Ausführung des WHERE-Codes der Spaltenwert möglicherweise noch nicht ermittelt wurde.
Kopiert von MySQL-Dokumentation
Wie in den Kommentaren gezeigt, kann die Verwendung von HAVING die Arbeit erledigen. Stellen Sie sicher, dass Sie dies lesen WHERE vs HAVING obwohl.
Wie Victor betonte, liegt das Problem beim Alias. Dies kann jedoch vermieden werden, indem der Ausdruck direkt in die WHERE x IN y -Klausel eingefügt wird:
SELECT `users`.`first_name`,`users`.`last_name`,`users`.`email`,SUBSTRING(`locations`.`raw`,-6,4) AS `guaranteed_postcode`
FROM `users` LEFT OUTER JOIN `locations`
ON `users`.`id` = `locations`.`user_id`
WHERE SUBSTRING(`locations`.`raw`,-6,4) NOT IN #this is where the fake col is being used
(
SELECT `postcode` FROM `postcodes` WHERE `region` IN
(
'australia'
)
)
Ich denke jedoch, dass dies sehr ineffizient ist, da die Unterabfrage für jede Zeile der äußeren Abfrage ausgeführt werden muss.
Standard-SQL (oder MySQL) erlaubt die Verwendung von Spaltenaliasen in einer WHERE-Klausel nicht, weil
bei der Auswertung der WHERE-Klausel wurde der Spaltenwert möglicherweise noch nicht ermittelt.
(von MySQL-Dokumentation ). Sie können den Spaltenwert in der [~ # ~] wobei [~ # ~] -Klausel berechnen, den Wert in einer Variablen speichern und Verwenden Sie es in der Feldliste. Zum Beispiel könnten Sie dies tun:
SELECT `users`.`first_name`, `users`.`last_name`, `users`.`email`,
@postcode AS `guaranteed_postcode`
FROM `users` LEFT OUTER JOIN `locations`
ON `users`.`id` = `locations`.`user_id`
WHERE (@postcode := SUBSTRING(`locations`.`raw`,-6,4)) NOT IN
(
SELECT `postcode` FROM `postcodes` WHERE `region` IN
(
'australia'
)
)
Dadurch wird vermieden, dass der Ausdruck wiederholt wird, wenn er kompliziert wird, sodass der Code leichter zu warten ist.
Vielleicht ist meine Antwort zu spät, aber das kann anderen helfen.
Sie können es mit einer anderen select-Anweisung einschließen und die where-Klausel verwenden.
SELECT * FROM (Select col1, col2,...) as t WHERE t.calcAlias > 0
calcAlias ist die berechnete Alias-Spalte.
Sie können die HAVING-Klausel für Filter verwenden, die in SELECT-Feldern und -Aliasen berechnet werden
Ich benutze MySQL 5.5.24 und der folgende Code funktioniert:
select * from (
SELECT `users`.`first_name`, `users`.`last_name`, `users`.`email`,
SUBSTRING(`locations`.`raw`,-6,4) AS `guaranteed_postcode`
FROM `users` LEFT OUTER JOIN `locations`
ON `users`.`id` = `locations`.`user_id`
) as a
WHERE guaranteed_postcode NOT IN --this is where the fake col is being used
(
SELECT `postcode` FROM `postcodes` WHERE `region` IN
(
'australia'
)
)
Standard-SQL verbietet Verweise auf Spalten-Aliase in einer WHERE-Klausel. Diese Einschränkung wird auferlegt, da bei der Auswertung der WHERE-Klausel der Spaltenwert möglicherweise noch nicht ermittelt wurde. Die folgende Abfrage ist beispielsweise ungültig:
SELECT ID, COUNT (*) AS cnt FROM Tabellenname WHERE cnt> 0 GROUP BY ID;
Sie können SUBSTRING (locations
.raw
, - 6,4) für where-Bedingung verwenden
SELECT `users`.`first_name`, `users`.`last_name`, `users`.`email`,
SUBSTRING(`locations`.`raw`,-6,4) AS `guaranteed_postcode`
FROM `users` LEFT OUTER JOIN `locations`
ON `users`.`id` = `locations`.`user_id`
WHERE SUBSTRING(`locations`.`raw`,-6,4) NOT IN #this is where the fake col is being used
(
SELECT `postcode` FROM `postcodes` WHERE `region` IN
(
'australia'
)
)