233

私が実行しているクエリは次のとおりですが、このエラーが発生しています。

#1054 - 「IN/ALL/ANY サブクエリ」の不明な列「guaranteed_postcode」

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 句で偽の列を使用できないのはなぜですか?

4

7 に答える 7

485

列のエイリアスは、GROUP BY、ORDER BY、または HAVING 句でのみ使用できます。

標準 SQL では、WHERE 句で列のエイリアスを参照できません。この制限が課されるのは、WHERE コードが実行されるときに、列の値がまだ決定されていない可能性があるためです。

MySQL ドキュメントからのコピー

コメントで指摘されているように、代わりに HAVING を使用するとうまくいく場合があります。この質問も必ず読んでください: WHERE vs HAVING

于 2009-06-03T00:38:20.100 に答える
24

ビクターが指摘したように、問題はエイリアスにあります。これは、式を 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'
 )
)

ただし、外部クエリのすべての行に対してサブクエリを実行する必要があるため、これは非常に非効率的だと思います。

于 2009-06-03T00:47:09.910 に答える
21

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

これにより、式が複雑になったときに式を繰り返す必要がなくなり、コードの保守が容易になります。

于 2012-07-27T10:14:13.480 に答える
8

SELECTフィールドとエイリアスで計算されたフィルターにHAVING句を使用できます

于 2015-04-14T09:40:48.647 に答える
1

私は 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'
 )
)
于 2012-09-07T14:39:00.633 に答える