Columna desconocida en la cláusula Where


126

Tengo una consulta simple:

SELECT u_name AS user_name FROM users WHERE user_name = "john";

Consigo Unknown Column 'user_name' in where clause. ¿No puedo hacer referencia 'user_name'en otras partes de la declaración incluso después select 'u_name as user_name'?

Respuestas:


94

SQL se evalúa al revés, de derecha a izquierda. Entonces, la cláusula where se analiza y evalúa antes de la cláusula select. Debido a esto, el aliasing de u_name a user_name aún no se ha producido.


30
En lugar de "al revés", creo que tiene más sentido decir "al revés"
Joe Phillips

44
Tiene más sentido decir que toda la declaración se analiza, transforma y optimiza como un todo en un proceso complejo de varias etapas. "SQL se evalúa al revés, de derecha a izquierda" es simplemente incorrecto
David Aldridge

3
respuesta incompleta ya que el usuario preguntó si se puede usar 'nombre_usuario' en la declaración, que puede ser después de, por ejemplo, '
TENER

45

Qué pasa:

SELECT u_name AS user_name FROM users HAVING user_name = "john";

16
¿Por qué usarías en HAVINGlugar de WHEREen este caso?
PeteGO

44
@PeteGO consulte la respuesta de Paul Dixon. tldr; Tener se evalúa más tarde que DONDE y, lo que es más importante, SELECCIONAR.
jairbow

38

Consulte la siguiente página del manual de MySQL: http://dev.mysql.com/doc/refman/5.0/en/select.html

"A select_expr se le puede dar un alias usando AS alias_name. El alias se usa como el nombre de columna de la expresión y se puede usar en las cláusulas GROUP BY, ORDER BY o HAVING".

(...)

No está permitido hacer referencia a un alias de columna en una cláusula WHERE, porque el valor de la columna aún no se puede determinar cuando se ejecuta la cláusula WHERE. Consulte la Sección B.5.4.4, "Problemas con los alias de columna".


Además, tenga en cuenta (del hombre de MySQL): el estándar SQL requiere que HAVING solo haga referencia a columnas en la cláusula GROUP BY o columnas utilizadas en funciones agregadas. Sin embargo, MySQL admite una extensión de este comportamiento y permite HACER que se refiera a columnas en la lista SELECCIONAR y también a columnas en subconsultas externas.
Vincent Pazeller

12
select u_name as user_name from users where u_name = "john";

Piénselo de esta manera, su cláusula where se evalúa primero, para determinar qué filas (o filas unidas) deben devolverse. Una vez que se ejecuta la cláusula where, se ejecuta la cláusula select.

Para decirlo mejor, imagine esto:

select distinct(u_name) as user_name from users where u_name = "john";

No se puede hacer referencia a la primera mitad sin la segunda. Donde siempre se evalúa primero, luego la cláusula select.


11

Si está intentando realizar una consulta como la siguiente (encuentre todos los nodos con al menos un archivo adjunto) donde ha utilizado una instrucción SELECT para crear un nuevo campo que en realidad no existe en la base de datos, e intente usar el alias para ese resultado te encontrarás con el mismo problema:

SELECT nodes.*, (SELECT (COUNT(*) FROM attachments 
WHERE attachments.nodeid = nodes.id) AS attachmentcount 
FROM nodes
WHERE attachmentcount > 0;

Obtendrá un error "Columna desconocida 'attachcount' en la cláusula WHERE".

La solución es bastante simple: simplemente reemplace el alias con la declaración que produce el alias, por ejemplo:

SELECT nodes.*, (SELECT (COUNT(*) FROM attachments 
WHERE attachments.nodeid = nodes.id) AS attachmentcount 
FROM nodes 
WHERE (SELECT (COUNT(*) FROM attachments WHERE attachments.nodeid = nodes.id) > 0;

Todavía obtendrá el alias devuelto, pero ahora SQL no debería molestar al alias desconocido.


1
Estaba enfrentando este problema exacto y encontré su respuesta: ¡gracias! Solo para tener en cuenta, es (comprensiblemente) un poco lento en grandes bases de datos, pero de todos modos estoy lidiando con una estúpida configuración de base de datos heredada.
Liam Newmarch

Creo que tiene un extra (en su consulta antes de (COUNT(*)que no esté cerrado en ningún lado.
tftd

3
¿Pero no se ejecuta la instrucción SELECT dos veces?
Matej

De lejos, no soy un experto en MySQL, pero esto parece muy impropio. He experimentado que las selecciones anidadas hacen que una consulta sea mucho más lenta.
GDY

8

Su definición aliasno es bienvenida por la WHEREcláusula que tiene que usar la HAVINGcláusula para esto

SELECT u_name AS user_name FROM users HAVING user_name = "john";

O puede usar directamente el nombre de la columna original con el WHERE

SELECT u_name AS user_name FROM users WHERE u_name = "john";

Igual que tiene el resultado en un alias definido por el usuario como resultado de una subconsulta o cualquier cálculo, la HAVINGcláusula no accederáWHERE

SELECT u_name AS user_name ,
(SELECT last_name FROM users2 WHERE id=users.id) as user_last_name
FROM users  WHERE u_name = "john" HAVING user_last_name ='smith'

7

Ya sea:

SELECT u_name AS user_name
FROM   users
WHERE  u_name = "john";

o:

SELECT user_name
from
(
SELECT u_name AS user_name
FROM   users
)
WHERE  u_name = "john";

El último debería ser el mismo que el primero si el RDBMS admite la inserción de predicados en la vista en línea.



5

No, debe seleccionarlo con el nombre correcto. Sin embargo, si proporcionó la tabla que seleccionó de un alias, puede usarla.



1

Columna desconocida en la WHEREcláusula causada por las líneas 1 y 2 y resuelta por la línea 3:

  1. $sql = "SELECT * FROM users WHERE username =".$userName;
  2. $sql = "SELECT * FROM users WHERE username =".$userName."";
  3. $sql = "SELECT * FROM users WHERE username ='".$userName."'";

¿Qué has cambiado y por qué? Además, ¿por qué publicaste código que está ampliamente abierto para inyecciones SQL?
Nico Haase

1

Puede ser de ayuda.

Usted puede

SET @somevar := '';
SELECT @somevar AS user_name FROM users WHERE (@somevar := `u_name`) = "john";

Funciona.

¡PERO ASEGÚRESE DE LO QUE HACE!

  • Los índices NO SE UTILIZAN aquí
  • Se escaneará TABLA COMPLETA: no ha especificado la parte LIMIT 1
  • Entonces, ESTA CONSULTA SERÁ SLLLOOOOOOW en mesas enormes.

Pero, puede ser útil en algunos casos


0

Si bien puede alias sus tablas dentro de su consulta (es decir, "SELECCIONE u.nombredeusuario DE usuarios u;"), debe usar los nombres reales de las columnas a las que hace referencia. AS solo afecta cómo se devuelven los campos.


Creo que puede usar el alias en algunos RDBMS como MySql, por ejemplo. Sin embargo, tienes razón para el servidor SQL.
PeteGO

0
SELECT user_name
FROM
(
SELECT name AS user_name
FROM   users
) AS test
WHERE  user_name = "john"

¿Por qué querrías usar una subconsulta? Mucho más simple sin.
PeteGO

0

Acabo de tener este problema.

Asegúrese de que no haya espacio en el nombre de la entidad en la base de datos.

por ejemplo, 'nombre_usuario' en lugar de 'nombre_usuario'


-1

intente su tarea usando la condición IN u OR y también esta consulta está trabajando en spark-1.6.x

 SELECT  patient, patient_id FROM `patient` WHERE patient IN ('User4', 'User3');

o

SELECT  patient, patient_id FROM `patient` WHERE patient = 'User1' OR patient = 'User2';

-1

Para mí, la raíz del problema era un número que copié para usar en una cláusula WHERE. El número tenía el símbolo "invisible", al menos para MySQL Workbench. Puse el número en la consola de Chrome, era claramente visible.


-2

Tuve el mismo problema, lo encontré útil.

mysql_query("SELECT * FROM `users` WHERE `user_name`='$user'");

recuerde poner $ user en '' comillas simples.


1
Ese código está ampliamente abierto para la inyección de SQL. Nadie debería usar este código para resolver el problema dado
Nico Haase
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.