sql—在mysql查询的where子句中使用列别名会产生错误

sy5wg1nm  于 2021-06-24  发布在  Mysql
关注(0)|答案(8)|浏览(399)

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

1054-“in/all/any子查询”中的未知列“邮政编码”

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 `guaranteed_postcode` NOT IN #this is where the fake col is being used
(
 SELECT `postcode` FROM `postcodes` WHERE `region` IN
 (
  'australia'
 )
)

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

bmvo0sr5

bmvo0sr51#

我使用的是MySQL5.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'
 )
)
kyvafyod

kyvafyod2#

正如维克托指出的,问题出在别名上。但是,可以通过将表达式直接放入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'
 )
)

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

wnavrhmk

wnavrhmk3#

也许我的回答太迟了,但这可以帮助别人。
您可以用另一个select语句将其括起来,并使用where子句对其执行操作。

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

calcalias是计算的别名列。

wrrgggsh

wrrgggsh4#

标准sql不允许在where子句中引用列别名。施加此限制是因为在计算where子句时,列值可能尚未确定。例如,以下查询是非法的:
选择id,count()as cnt from tbl\u name where cnt>0 group by id,从tbl\u name中选择id,count()作为cnt;

67up9zun

67up9zun5#

只能在group by、order by或having子句中使用列别名。
标准sql不允许您在where子句中引用列别名。施加此限制是因为当执行where代码时,列值可能尚未确定。
从mysql文档复制
正如评论中所指出的,用have代替have可以完成这项工作。一定要读一读这个问题:在哪里vs有。

woobm2wo

woobm2wo6#

标准sql(或mysql)不允许在where子句中使用列别名,因为
在计算where子句时,列值可能尚未确定。
(来自mysql文档)。您可以在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'
 )
)

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

pepwfjgg

pepwfjgg7#

您可以使用having子句在选择字段和别名中计算筛选器

zsbz8rwp

zsbz8rwp8#

可以使用子字符串( locations . raw ,-6,4)适用于何处条件

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'
)
)

相关问题