webentwicklung-frage-antwort-db.com.de

Die Verwendung des Spaltenalias in der WHERE-Klausel der MySQL-Abfrage führt zu einem Fehler

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?

176
James

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.

397
victor hugo

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.

23
rodion

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.

19
Joni

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.

14
George Khouri

Sie können die HAVING-Klausel für Filter verwenden, die in SELECT-Feldern und -Aliasen berechnet werden

8
Hett

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'
 )
)
1
themis

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;

0
Pavan Rajput

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'
)
)