140

我有一个简单的查询:

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

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

4

17 回答 17

106

SQL 是从右到左向后计算的。因此 where 子句在 select 子句之前被解析和评估。因此,尚未发生 u_name 到 user_name 的别名。

于 2008-09-30T15:41:00.060 回答
57

关于什么:

SELECT u_name AS user_name FROM users HAVING user_name = "john";
于 2010-10-04T15:03:43.537 回答
39

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

“可以使用 AS alias_name 为 select_expr 赋予别名。别名用作表达式的列名,可用于 GROUP BY、ORDER BY 或 HAVING 子句。”

(...)

不允许在 WHERE 子句中引用列别名,因为在执行 WHERE 子句时可能尚未确定列值。请参阅第 B.5.4.4 节,“列别名问题”。

于 2008-09-30T15:44:29.707 回答
13
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";

没有后半部分就不能参考前半部分。where 总是首先被评估,然后是 select 子句。

于 2008-09-30T15:41:35.190 回答
11

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

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

您将收到错误“WHERE 子句中的未知列 'attachmentcount'”。

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

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 不应该在未知别名上出现问题。

于 2011-05-26T11:04:29.073 回答
9

您定义的条款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'
于 2013-07-30T17:28:09.993 回答
7

任何一个:

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 支持将谓词推入内联视图,则后者应该与前者相同。

于 2008-09-30T15:41:33.833 回答
6

更正:

SELECT u_name AS user_name FROM users WHERE u_name = 'john';
于 2008-09-30T15:39:50.437 回答
5

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

于 2008-09-30T15:38:50.267 回答
2

你不能。user_name 直到返回时间才存在。

于 2008-09-30T15:38:22.763 回答
1
SELECT user_name
FROM
(
SELECT name AS user_name
FROM   users
) AS test
WHERE  user_name = "john"
于 2009-04-23T08:44:53.427 回答
1

子句中的未知列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."'";
于 2010-01-28T23:06:49.907 回答
1

可能会有所帮助。

你可以

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

有用。

但要确保你做什么!

  • 此处不使用索引
  • 将扫描 FULL TABLE - 您尚未指定 LIMIT 1 部分
  • 所以, - 这个查询将在巨大的桌子上 SLLLOOOOOOW。

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

于 2011-11-22T10:59:09.917 回答
0

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

于 2008-09-30T15:41:37.530 回答
0

刚遇到这个问题。

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

例如“用户名”而不是“用户名”

于 2015-04-02T15:15:57.520 回答
-1

对我来说,问题的根源是我复制的一个数字,以便在 WHERE 子句中使用。该数字具有“隐形”符号,至少对于 MySQL Workbench 而言。我将数字放在 Chrome 控制台中,它清晰可见。

于 2020-01-20T15:10:40.363 回答
-2

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

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

记得将 $user 放在 ' ' 单引号中。

于 2013-01-05T10:05:54.597 回答