MySQLのクエリの句がエラーを生成しますWHEREで使用する列の別名

StackOverflow https://stackoverflow.com/questions/942571

  •  09-09-2019
  •  | 
  •  

質問

私が実行しているクエリがあり、次のように、しかし、私はこのエラーを取得しています:

  

#1054 - 不明な列 'guaranteed_postcode' '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句に偽の列を使用することができません。

役に立ちましたか?

解決

あなただけのGROUP BY、ORDER BY、またはHAVING句で列の別名を使用することができます。

  

標準SQLは、あなたがすることはできません。   WHEREで列の別名を参照してください。   句。この制限は課され   WHEREコードがあるとき理由   実行され、列の値がまだないかもしれません   決定されます。

MySQLのドキュメント コメントで指摘したように、

、代わりにHAVING使用して作業を行うことができます。この WHEREしかしのHAVING対にしてくださいます。

他のヒント

ビクターが指摘したように、

、問題が別名です。これは、WHERE xの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句が評価されたときに、

、列の値がまだ決定されていない可能性があります。

MySQLのドキュメントするから) 。あなたにできることは、の句で列の値を計算し、変数に値を保存し、フィールドリストでそれを使用しています。たとえば、あなたがこれを行うことができます:

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

これは、複雑な成長したときに維持しやすいコードを作り、式を繰り返し避けます。

たぶん、私の答えは手遅れであるが、これは他の人を助けることができます。

あなたは別のselect文でそれを囲み、それにwhere句を使用することができます。

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

calcAliasを算出したエイリアスカラムである。

あなたは、SELECTフィールドと別名で算出されたフィルタのためにHAVING句を使用することができます。

私は、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'
 )
)

標準SQLはWHERE句で列の別名への参照を禁止します。 WHERE句が評価されるとき、列の値がまだ決定されていないかもしれないので、この制限が課されます。たとえば、次のクエリは違法です。

SELECT ID、COUNT(*)IDでtbl_nameをWHERE CNT> 0群からCNT AS;

あなたはどこ条件のSUBSTRING(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'
)
)
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top