Where 子句中的未知列

我有一个简单的问题:

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

我得到了 Unknown Column 'user_name' in where clause。即使在 select 'u_name as user_name'之后,我能不能不在声明的其他部分提到 'user_name'

355233 次浏览

不可以。 user _ name 在返回时间之前不存在。

不,你需要用正确的名字选择它。如果给出了从别名中选择的表,则可以使用该别名。

更正:

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

SQL 是从右到左向后计算的。所以 where 子句在 select 子句之前被解析和计算。由于这个原因,u _ name 到 user _ name 的别名还没有发生。

或者:

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

或:

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

如果 RDBMS 支持谓词推送到内联视图中,那么后者应该与前者相同。

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

可以这样想,where 子句首先求值,以确定需要返回哪些行(或连接的行)。执行 where 子句后,select 子句将为其运行。

换句话说,想象一下:

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

不能引用前半部分而不引用后半部分。凡总是先求值,然后是 select 子句。

虽然可以在查询中使用表的别名(例如,“ SELECT u.username FROM users u;”) ,但是必须使用所引用的列的实际名称。AS 只影响字段的返回方式。

请参阅下面的 MySQL 手册页: http://dev.mysql.com/doc/refman/5.0/en/select.html

”可以给 select _ expr 一个别名 使用 AS alias _ name 作为表达式的列名和 可以在 GROUPBY、 ORDERBY 或 有条款”

(...)

不允许在 WHERE 子句中引用列别名, 因为在 WHERE 时可能尚未确定列值 参见 B.5.4.4节“与列有关的问题” 化名。

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

WHERE子句中的未知列由第1行和第2行引起,并由第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."'";

那么:

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

如果你试图执行如下查询(查找所有至少有一个附件的节点) ,其中你使用了一个 SELECT 语句来创建一个实际上不存在于数据库中的新字段,并尝试使用该结果的别名,你会遇到同样的问题:

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

您将得到一个错误“未知列‘ attachmentcount’in WHERE 子句”。

解决方案实际上相当简单——只需将别名替换为生成别名的语句,例如:

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;

您仍然可以得到别名返回,但是现在 SQL 不应该停留在未知的别名上。

也许会有帮助。

你可以的

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

有用。

但是你要确定你做了什么!

  • 这里不使用索引
  • 将有扫描全表-您没有指定的限制1部分
  • 因此,-这个查询在巨大的表上会很慢。

但是,在某些情况下可能会有帮助

我也有同样的问题,我发现这个很有用。

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

记住把 $user 放在单引号中。

您所定义的 alias不受 WHERE子句的欢迎,因此必须使用 HAVING子句

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

或者可以直接使用原来的列名和 WHERE

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

与子查询或任何计算的结果在用户定义的别名中的结果相同,它将由 HAVING子句访问,而不是由 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'

只是有个问题。

确保数据库中的实体名称中没有空格。

例如‘ user _ name’而不是‘ user _ name’