我有一个简单的查询:
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'
吗?
SQL从右到左向后评估.因此,在select子句之前解析和评估where子句.因此,尚未发生u_name到user_name的别名.
关于什么:
SELECT u_name AS user_name FROM users HAVING user_name = "john";
请参阅以下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节"列别名的问题".
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语句创建一个实际上不存在于数据库中的新字段,并尝试使用该结果的别名你将遇到同样的问题:
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不应该使用未知别名.
您必须使用该条款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'
更正:
SELECT u_name AS user_name FROM users WHERE u_name = 'john';
或者:
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支持谓词推入内联视图,后者应该与前者相同.
不需要选择正确的名称.如果你给了表,你可以从别名中选择,但是你可以使用它.