Where 子句中的未知列

Posted

技术标签:

【中文标题】Where 子句中的未知列【英文标题】:Unknown Column In Where Clause 【发布时间】:2008-09-30 15:37:17 【问题描述】:

我有一个简单的查询:

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' 吗?

【问题讨论】:

【参考方案1】:

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

【讨论】:

比起“向后”,我认为说“由内而外”更有意义 在一个复杂的多阶段过程中将整个语句作为一个整体进行解析、转换和优化更有意义。 “SQL 是从右到左向后评估的”是错误的 不完整的答案,因为用户询问是否可以在语句中使用'user_name',它可以在例如之后'拥有'【参考方案2】:

怎么样:

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

【讨论】:

在这种情况下为什么要使用HAVING 而不是WHERE @PeteGO 参考 Paul Dixon 的回答。 tldr; HAVING 的评估晚于 WHERE,更重要的是 SELECT。【参考方案3】:

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

"一个 select_expr 可以被赋予一个别名 使用 AS 别名。使用了别名 作为表达式的列名和 可用于 GROUP BY、ORDER BY 或 HAVING 子句。”

(...)

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

【讨论】:

另外,请注意(来自 MySQL man):SQL 标准要求 HAVING 必须仅引用 GROUP BY 子句中的列或聚合函数中使用的列。但是,MySQL 支持对此行为的扩展,并允许 HAVING 引用 SELECT 列表中的列和外部子查询中的列。【参考方案4】:
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 子句。

【讨论】:

【参考方案5】:

如果您尝试执行如下查询(查找所有具有至少一个附件的节点),其中您使用 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 不应该在未知别名处出错。

【讨论】:

我遇到了这个确切的问题,并遇到了您的答案 - 谢谢!请注意,在大型数据库上它(可以理解)有点慢,但无论如何我正在处理一个愚蠢的继承数据库设置。 我相信您的查询中有一个额外的((COUNT(*) 之前,它不会在任何地方关闭。 但是SELECT语句不是运行两次吗? 我目前还不是 mysql 专家,但这似乎非常不规范。我体验过嵌套选择会使查询慢得多。【参考方案6】:

WHERE 子句不欢迎您定义的alias,您必须为此使用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'

【讨论】:

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

【讨论】:

【参考方案8】:

更正:

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

【讨论】:

【参考方案9】:

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

【讨论】:

【参考方案10】:

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

【讨论】:

【参考方案11】:
SELECT user_name
FROM
(
SELECT name AS user_name
FROM   users
) AS test
WHERE  user_name = "john"

【讨论】:

为什么要使用子查询?没有就简单多了。【参考方案12】:

WHERE 子句中的未知列由第 1 行和第 2 行引起并由第 3 行解决:

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

【讨论】:

你改变了什么,为什么?此外,您为什么发布对 SQL 注入广泛开放的代码?【参考方案13】:

可能会有帮助。

你可以

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

有效。

但要确定你做什么!

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

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

【讨论】:

【参考方案14】:

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

【讨论】:

我认为您可以在某些 RDBMS 中使用别名,例如 MySql。不过,您对 Sql Server 是正确的。【参考方案15】:

刚刚遇到这个问题。

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

例如'user_name' 而不是 'user_name'

【讨论】:

【参考方案16】:

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

【讨论】:

【参考方案17】:

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

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

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

【讨论】:

该代码对 SQL 注入广泛开放。没有人应该使用此代码来解决给定的问题

以上是关于Where 子句中的未知列的主要内容,如果未能解决你的问题,请参考以下文章

Where 子句中的未知列

“where 子句”中的未知列在程序中失败

即使插入了列,“WHERE”子句中的 SQL 未知列

错误代码:1054。“where 子句”中的未知列“sdate”

查询中的错误 (1054):“where 子句”中的未知列“TableValue”

简单选择语句的where子句中的MySQL未知列