El uso de alias de columna en la cláusula WHERE de la consulta MySQL produce un error
La consulta que estoy ejecutando es la siguiente, sin embargo, estoy recibiendo este error:
#1054-Unknown column 'guaranteed_postcode ' in'IN/ALL/ANY subquery'
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'
)
)
Mi pregunta es: ¿por qué no puedo usar una columna falsa en la cláusula where de la misma consulta de BD?
8 answers
Solo puede usar alias de columna en las cláusulas GROUP BY, ORDER BY o HAVING.
SQL estándar no le permite refiérase a un alias de columna en una DONDE clausula. Esta restricción se impone porque cuando el código DONDE está ejecutado, el valor de la columna aún no puede sé decidido.
Copiado de Documentación MySQL
Como se señala en los comentarios, usar TENER en su lugar puede hacer el trabajo. Asegúrese de dar una lectura en este DONDE vs TENER aunque.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-25 18:06:56
Como Victor señaló, el problema es con el alias. Sin embargo, esto se puede evitar poniendo la expresión directamente en la cláusula WHERE x IN y:
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'
)
)
Sin embargo, supongo que esto es muy ineficiente, ya que la subconsulta tiene que ejecutarse para cada fila de la consulta externa.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-03 00:47:09
SQL estándar (o MySQL) no permite el uso de alias de columna en una cláusula WHERE porque
Cuando se evalúa la cláusula WHERE, es posible que el valor de la columna aún no se haya determinado.
(de documentación MySQL ). Lo que puede hacer es calcular el valor de la columna en la cláusula WHERE, guardar el valor en una variable y usarlo en la lista de campos. Por ejemplo, usted podría hacer esto:
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'
)
)
Esto evita repetir la expresión cuando se complica, haciendo que el código sea más fácil de mantener.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-20 05:30:27
Tal vez mi respuesta es demasiado tarde, pero esto puede ayudar a otros.
Puede encerrarlo con otra instrucción select y usar la cláusula where.
SELECT * FROM (Select col1, col2,...) as t WHERE t.calcAlias > 0
CalcAlias es la columna alias que se calculó.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-29 13:03:31
Puede usar la cláusula HAVING para el filtro calculado en SELECCIONAR campos y alias
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-15 07:35:12
Estoy usando mysql 5.5.24 y el siguiente código funciona:
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'
)
)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-09 03:13:02
SQL estándar no permite referencias a alias de columna en una cláusula WHERE. Esta restricción se impone porque cuando se evalúa la cláusula WHERE, es posible que el valor de la columna aún no se haya determinado. Por ejemplo, la siguiente consulta es ilegal:
SELECCIONE id, CUENTE(*) COMO cnt DESDE tbl_name DONDE cnt > 0 AGRUPA POR id;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-27 05:28:31
Puede usar SUBCADENA(locations
.raw
, -6,4) para donde conditon
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'
)
)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-21 10:02:21