Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在MySQL查询的WHERE子句中使用列别名会产生错误_Mysql_Sql_Mysql Error 1054 - Fatal编程技术网

在MySQL查询的WHERE子句中使用列别名会产生错误

在MySQL查询的WHERE子句中使用列别名会产生错误,mysql,sql,mysql-error-1054,Mysql,Sql,Mysql Error 1054,我正在运行的查询如下所示,但是我得到了以下错误: 1054-在/ALL/ANY子查询中的未知列“保证的邮政编码” 我的问题是:为什么我不能在同一DB查询的where子句中使用假列?您只能在GROUP BY、ORDER BY或HAVING子句中使用列别名 标准SQL不允许您 在其中引用列别名 条款这一限制是强加的 因为当代码在哪里时 如果已执行,则列值可能尚未执行 下定决心 抄袭 正如评论中所指出的,用have代替have可以完成这项工作。请务必阅读这个问题:。正如维克托指出的,问题在于别名。但是

我正在运行的查询如下所示,但是我得到了以下错误:

1054-在/ALL/ANY子查询中的未知列“保证的邮政编码”


我的问题是:为什么我不能在同一DB查询的where子句中使用假列?

您只能在GROUP BY、ORDER BY或HAVING子句中使用列别名

标准SQL不允许您 在其中引用列别名 条款这一限制是强加的 因为当代码在哪里时 如果已执行,则列值可能尚未执行 下定决心

抄袭


正如评论中所指出的,用have代替have可以完成这项工作。请务必阅读这个问题:。

正如维克托指出的,问题在于别名。但是,可以通过将表达式直接放入WHERE x IN y子句中来避免这种情况:

SELECT `users`.`first_name`,`users`.`last_name`,`users`.`email`,SUBSTRING(`locations`.`raw`,-6,4) AS `guaranteed_postcode`
FROM `users` LEFT OUTER JOIN `locations`
ON `users`.`id` = `locations`.`user_id`
WHERE SUBSTRING(`locations`.`raw`,-6,4) NOT IN #this is where the fake col is being used
(
 SELECT `postcode` FROM `postcodes` WHERE `region` IN
 (
  'australia'
 )
)

但是,我想这是非常低效的,因为必须为外部查询的每一行执行子查询。

标准SQL或MySQL不允许在WHERE子句中使用列别名,因为

计算WHERE子句时,可能尚未确定列值

从。您可以做的是计算WHERE子句中的列值,将该值保存在变量中,然后在字段列表中使用它。例如,您可以这样做:

SELECT `users`.`first_name`, `users`.`last_name`, `users`.`email`,
@postcode AS `guaranteed_postcode`
FROM `users` LEFT OUTER JOIN `locations`
ON `users`.`id` = `locations`.`user_id`
WHERE (@postcode := SUBSTRING(`locations`.`raw`,-6,4)) NOT IN
(
 SELECT `postcode` FROM `postcodes` WHERE `region` IN
 (
  'australia'
 )
)

这样可以避免在表达式变得复杂时重复该表达式,从而使代码更易于维护。

我使用的是mysql 5.5.24,以下代码有效:

select * from (
SELECT `users`.`first_name`, `users`.`last_name`, `users`.`email`,
SUBSTRING(`locations`.`raw`,-6,4) AS `guaranteed_postcode`
FROM `users` LEFT OUTER JOIN `locations`
ON `users`.`id` = `locations`.`user_id`
) as a
WHERE guaranteed_postcode NOT IN --this is where the fake col is being used
(
 SELECT `postcode` FROM `postcodes` WHERE `region` IN
 (
  'australia'
 )
)

也许我的回答太晚了,但这可以帮助其他人

您可以用另一个select语句将其括起来,并使用where子句对其进行排序

SELECT * FROM (Select col1, col2,...) as t WHERE t.calcAlias > 0

calcAlias是已计算的别名列。

您可以使用HAVING子句作为在选择字段和别名中计算的筛选器。

您可以使用SUBSTRINGlocations.raw,-6,4作为where条件

SELECT `users`.`first_name`, `users`.`last_name`, `users`.`email`,
SUBSTRING(`locations`.`raw`,-6,4) AS `guaranteed_postcode`
FROM `users` LEFT OUTER JOIN `locations`
ON `users`.`id` = `locations`.`user_id`
WHERE SUBSTRING(`locations`.`raw`,-6,4) NOT IN #this is where the fake col is being used
(
SELECT `postcode` FROM `postcodes` WHERE `region` IN
(
 'australia'
)
)

为快速准确的响应干杯!我已经研究了HAVING子句,并找到了一种成功运行此查询的方法。再次感谢。如果其他人有与我相同的问题,即在where子句中使用别名col失败-将“where”替换为“已立即修复+1个好答案”。@megaSteve4我确实有同样的问题!使用已顺利解决的工具在您的情况下,这可能很重要,也可能不重要,但是have的执行速度比have的工作速度慢,原因是必须在到达have时计算列值。如前所述,where不是这种情况。这与文档不冲突吗?作为一般规则,您永远不应该为用户变量赋值并读取同一语句中的值。你可能会得到你期望的结果,但这不是保证。这绝对是要记住的。但这对我来说一直很有效,我认为语句不同部分的求值顺序必须先确定在哪里,然后选择,然后分组,。。。但我没有这方面的参考:一些示例选择@code:=sum2,2*@code在MySQL 5.5中工作,但在5.6中,第二列在第一次调用时生成NULL,再次运行时返回前一个结果的2倍。有趣的是,选择@code:=2,2*@code和选择@code:=rand,2*@code在我今天的5.6版本中似乎都能工作。但这些确实是选择条款中的书写和阅读;在你的情况下,你把它设置在何处。@Joni,为什么不只评估两次条件呢?当然,MySQL足够聪明,可以优化……@Pacerier必须重复表达式的情况更糟,尤其是如果表达式很复杂的话。我无法确认MySQL是否实现了公共子表达式消除。@rodion,是的,我认为这是非常缓慢和低效的。@fahimg23-不确定。我试图找到一个原因,但我找不到!不过,要记住地点和拥有的区别。它们不一样。更新:这是因为提供了相同的解决方案,但有更多的信息。
SELECT `users`.`first_name`, `users`.`last_name`, `users`.`email`,
SUBSTRING(`locations`.`raw`,-6,4) AS `guaranteed_postcode`
FROM `users` LEFT OUTER JOIN `locations`
ON `users`.`id` = `locations`.`user_id`
WHERE SUBSTRING(`locations`.`raw`,-6,4) NOT IN #this is where the fake col is being used
(
SELECT `postcode` FROM `postcodes` WHERE `region` IN
(
 'australia'
)
)