Coluna desconhecida na cláusula Where


126

Eu tenho uma consulta simples:

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

Eu entendo Unknown Column 'user_name' in where clause. Não posso me referir 'user_name'em outras partes da declaração mesmo depois select 'u_name as user_name'?

Respostas:


94

O SQL é avaliado ao contrário, da direita para a esquerda. Portanto, a cláusula where é analisada e avaliada antes da cláusula select. Por esse motivo, o alias de u_name para user_name ainda não ocorreu.


30
Ao invés de "para trás" Eu acho que faz mais sentido dizer "fora para dentro"
— Joe Phillips

4
Faz mais sentido dizer que toda a declaração é analisada, transformada e otimizada como um todo em um processo complexo e de vários estágios. "SQL é avaliado ao contrário, da direita para a esquerda" está errado
— David Aldridge

3
resposta incompleta quando o usuário perguntou se 'user_name' pode ser usado na instrução, que pode ser posterior a, por exemplo, 'HAVING'
— luke_mclachlan

45

A respeito:

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

16
Por que você usaria em HAVINGvez de WHEREneste caso?
— PeteGO

4
@PeteGO consulte a resposta de Paul Dixon. tldr; HAVING é avaliado depois de WHERE e, mais importante, SELECT.
— Jairbow

38

Consulte a seguinte página de manual do MySQL: http://dev.mysql.com/doc/refman/5.0/en/select.html

"Um select_expr pode receber um alias usando AS alias_name. O alias é usado como o nome da coluna da expressão e pode ser usado nas cláusulas GROUP BY, ORDER BY ou HAVING."

(...)

Não é permitido fazer referência a um alias de coluna em uma cláusula WHERE, porque o valor da coluna ainda não pode ser determinado quando a cláusula WHERE for executada. Consulte a Seção B.5.4.4, “Problemas com aliases de coluna”.


Observe também (do homem MySQL): O padrão SQL requer que HAVING faça referência apenas a colunas da cláusula GROUP BY ou colunas usadas em funções agregadas. No entanto, o MySQL suporta uma extensão para esse comportamento e permite que HAVING se refira às colunas na lista SELECT e às colunas nas subconsultas externas.
— Vincent Pazeller

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

Pense assim, sua cláusula where avalia primeiro, para determinar quais linhas (ou linhas unidas) precisam ser retornadas. Depois que a cláusula where é executada, a cláusula select é executada.

Para colocar de uma maneira melhor, imagine o seguinte:

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

Você não pode fazer referência à primeira metade sem a segunda. Onde sempre é avaliado primeiro, depois a cláusula select.


11

Se você estiver tentando executar uma consulta como a seguinte (encontre todos os nós com pelo menos um anexo) em que você usou uma instrução SELECT para criar um novo campo que não existe realmente no banco de dados e tente usar o alias para esse resultado, você encontrará o mesmo problema:

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

Você receberá um erro "Coluna desconhecida 'attachmentcount' na cláusula WHERE".

A solução é realmente bastante simples - basta substituir o alias pela declaração que produz o alias, por exemplo:

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;

Você ainda receberá o alias retornado, mas agora o SQL não deve trabalhar com o alias desconhecido.


1
Eu estava enfrentando esse problema exato e me deparei com sua resposta - obrigado! Apenas para observar, é (compreensivelmente) um pouco lento em bancos de dados grandes, mas estou lidando com uma configuração estúpida de banco de dados herdada.
— Liam Newmarch

Acredito que você tenha um extra (na sua consulta antes da (COUNT(*)que não seja fechada em nenhum lugar.
— tftd

3
Mas a instrução SELECT não é executada duas vezes?
— Matej 25/02

Eu não sou de longe nenhum especialista em mysql, mas isso parece muito pouco desempenho. Eu experimentei que seleções aninhadas tornam uma consulta muito mais lenta.
— GDY

8

Seu definido aliasnão é bem-vindo pela WHEREcláusula em que você deve usar a HAVINGcláusula para este

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

OU você pode usar diretamente o nome da coluna original com o WHERE

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

O mesmo que o resultado no alias definido pelo usuário como resultado da subconsulta ou de qualquer cálculo que será acessado pela HAVINGcláusula e não peloWHERE

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

Ou:

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

ou:

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

O último deve ser o mesmo que o primeiro se o RDBMS suportar o envio de predicado para a exibição em linha.



5

Não, você precisa selecioná-lo com o nome correto. Se você forneceu a tabela que selecionou de um alias, você pode usá-lo.



1

Coluna desconhecida na WHEREcláusula causada pelas linhas 1 e 2 e resolvida pela linha 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."'";

O que você mudou e por quê? Além disso, por que você postou um código amplamente aberto para injeções de SQL?
— Nico Haase

1

Pode ser que ajude.

Você pode

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

Funciona.

MAS TENHA CERTEZA DO QUE VOCÊ FAZ!

  • Os índices NÃO SÃO USADOS aqui
  • Será analisada a TABELA COMPLETA - você não especificou a parte LIMIT 1
  • Então, - ESTA CONSULTA SERÁ INCLUÍDA em grandes mesas.

Mas, pode ser que isso ajude em alguns casos


0

Embora você possa criar um alias de suas tabelas em sua consulta (por exemplo, "SELECT u.username FROM users u;"), você deve usar os nomes reais das colunas às quais está fazendo referência. O AS afeta apenas como os campos são retornados.


Eu acho que você pode usar o alias em alguns RDBMS como o MySql, por exemplo. Você está correto para o Sql Server.
— PeteGO

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

Por que você deseja usar uma subconsulta? Muito mais simples sem.
— PeteGO

0

Só tive esse problema.

Verifique se não há espaço no nome da entidade no banco de dados.

por exemplo, 'nome_do_usuário' em vez de 'nome_do_usuário'


-1

tente sua tarefa usando a condição IN ou OR e também esta consulta está funcionando no spark-1.6.x

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

ou

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

-1

Para mim, a raiz do problema era um número que copiei para usar em uma cláusula WHERE. O número tinha o símbolo "invisível", pelo menos para o MySQL Workbench. Coloquei o número no console do Chrome que estava claramente visível.


-2

Eu tive o mesmo problema, achei isso útil.

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

lembre-se de colocar $ user em '' aspas simples.


1
Esse código é amplamente aberto para injeção de SQL. Ninguém deve usar este código para resolver o problema dado
— Nico Haase
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.