Colonna sconosciuta nella clausola Where


126

Ho una semplice domanda:

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

Ho capito Unknown Column 'user_name' in where clause. Non posso fare riferimento 'user_name'in altre parti della dichiarazione anche dopo select 'u_name as user_name'?

Risposte:


94

SQL viene valutato al contrario, da destra a sinistra. Quindi la clausola where viene analizzata e valutata prima della clausola select. Per questo motivo l'aliasing di u_name su user_name non è ancora avvenuto.


30
Piuttosto che "all'indietro" penso che abbia più senso dire "dentro e fuori"
Joe Phillips,

4
Ha più senso dire che l'intera istruzione viene analizzata, trasformata e ottimizzata nel suo insieme in un processo complesso, a più fasi. "SQL viene valutato al contrario, da destra a sinistra" è semplicemente sbagliato
David Aldridge,

3
risposta incompleta quando l'utente ha chiesto se "user_name" può essere utilizzato
nell'istruzione

45

Che dire:

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

16
Perché dovresti usare HAVINGinvece che WHEREin questo caso?
PeteGO,

4
@PeteGO si riferisce alla risposta di Paul Dixon. TLDR; HAVING viene valutato più tardi di WHERE e, soprattutto, SELEZIONA.
jairbow,

38

Vedere la seguente pagina di manuale di MySQL: http://dev.mysql.com/doc/refman/5.0/en/select.html

"A select_expr può essere assegnato un alias utilizzando AS alias_name. L'alias viene utilizzato come nome della colonna dell'espressione e può essere utilizzato nelle clausole GROUP BY, ORDER BY o HAVING."

(...)

Non è consentito fare riferimento a un alias di colonna in una clausola WHERE, poiché il valore della colonna potrebbe non essere ancora determinato quando viene eseguita la clausola WHERE. Vedere la sezione B.5.4.4, "Problemi con gli alias di colonna".


Inoltre, nota (dall'uomo di MySQL): lo standard SQL richiede che HAVING debba fare riferimento solo alle colonne nella clausola GROUP BY o alle colonne utilizzate nelle funzioni di aggregazione. Tuttavia, MySQL supporta un'estensione di questo comportamento e consente ad HAVING di fare riferimento alle colonne nell'elenco SELECT e anche alle colonne nelle sottoquery esterne.
Vincent Pazeller,

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

Pensala in questo modo, la clausola where viene valutata per prima, per determinare quali righe (o righe unite) devono essere restituite. Una volta eseguita la clausola where, viene eseguita la clausola select.

Per dirla in modo migliore, immagina questo:

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

Non puoi fare riferimento alla prima metà senza la seconda. Dove viene sempre valutato prima, quindi la clausola select.


11

Se si sta tentando di eseguire una query come la seguente (trovare tutti i nodi con almeno un allegato) in cui è stata utilizzata un'istruzione SELECT per creare un nuovo campo che in realtà non esiste nel database e provare a utilizzare l'alias per quel risultato ti imbatterai nello stesso problema:

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

Verrà visualizzato un messaggio di errore "Colonna sconosciuta" allegato conteggio "nella clausola WHERE".

La soluzione è in realtà abbastanza semplice: basta sostituire l'alias con l'affermazione che produce l'alias, ad esempio:

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;

Otterrai comunque restituito l'alias, ma ora SQL non dovrebbe superare l'alias sconosciuto.


1
Stavo affrontando questo esatto problema e ho trovato la tua risposta - grazie! Solo per notare, è (comprensibilmente) un po 'lento su database di grandi dimensioni, ma ho comunque a che fare con una stupida configurazione del database ereditato.
Liam Newmarch,

Credo che tu abbia un extra (nella tua query prima (COUNT(*)che non sia chiusa da nessuna parte.
tftd

3
Ma l'istruzione SELECT non viene eseguita due volte?
Matej,

Non sono di gran lunga un esperto di mysql ma questo sembra molto inefficiente. Ho sperimentato che le selezioni nidificate rendono una query molto più lenta.
GDY

8

Il tuo definito aliasnon è accolto favorevolmente dalla WHEREclausola che devi usare la HAVINGclausola per questo

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

O è possibile utilizzare direttamente il nome della colonna originale con il WHERE

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

Come nel caso in cui il risultato sia un alias definito dall'utente a seguito di una query secondaria o di qualsiasi calcolo a cui accederà dalla HAVINGclausola e non dalWHERE

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

O:

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";

Il secondo dovrebbe essere lo stesso del primo se RDBMS supporta il predicato spingendo nella vista in linea.



5

No, è necessario selezionarlo con il nome corretto. Se hai dato la tabella selezionata da un alias, puoi comunque usarla.



1

Colonna sconosciuta nella WHEREclausola causata dalle righe 1 e 2 e risolta dalla riga 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."'";

Cosa hai cambiato e perché? Inoltre, perché hai pubblicato codice che è ampiamente aperto per iniezioni di SQL?
Nico Haase,

1

Può essere d'aiuto.

Puoi

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

Funziona.

MA ASSICURATI CHE COSA FARE!

  • Gli indici NON SONO UTILIZZATI qui
  • Verrà scansionata la TABELLA COMPLETA - non hai specificato la parte LIMIT 1
  • Quindi, - QUESTA QUESTIONE SARÀ SLLLOOOOOOW su tavoli enormi.

Ma potrebbe essere utile in alcuni casi


0

Mentre puoi aliasare le tue tabelle all'interno della tua query (es. "SELEZIONAnomeutente DA utenti u;"), devi usare i nomi effettivi delle colonne a cui fai riferimento. AS influisce solo sulla modalità di restituzione dei campi.


Penso che tu possa usare l'alias in alcuni RDBMS come MySql per esempio. Tuttavia, sei corretto per SQL Server.
PeteGO,

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

Perché dovresti usare una sottoquery? Molto più semplice senza.
PeteGO,

0

Ho appena avuto questo problema.

Assicurarsi che non vi sia spazio nel nome dell'entità nel database.

ad es. "nome_utente" anziché "nome_utente"


-1

prova la tua attività usando la condizione IN o la condizione OR e anche questa query funziona su 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

Per me la radice del problema era un numero che ho copiato per usarlo in una clausola WHERE. Il numero aveva il simbolo "invisibile", almeno per MySQL Workbench. Ho inserito il numero nella console di Chrome che era chiaramente visibile.


-2

Ho avuto lo stesso problema, l'ho trovato utile.

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

ricordati di mettere $ user tra virgolette singole.


1
Tale codice è ampiamente aperto per l'iniezione SQL. Nessuno dovrebbe usare questo codice per risolvere il problema dato
Nico Haase,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.