[mysql] MySQL 쿼리의 WHERE 절에서 열 별칭을 사용하면 오류가 발생합니다

내가 실행중인 쿼리는 다음과 같지만이 오류가 발생합니다.

# 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 절에서 가짜 열을 사용할 수 없습니까?



답변

GROUP BY, ORDER BY 또는 HAVING 절에는 열 별명 만 사용할 수 있습니다.

표준 SQL을 사용하면 WHERE 절에서 열 별칭을 참조 할 수 없습니다. WHERE 코드가 실행될 때 열 값이 아직 결정되지 않았기 때문에 이러한 제한이 적용됩니다.

MySQL 문서 에서 복사

주석에서 지적했듯이 HAVING을 대신 사용하면 작업을 수행 할 수 있습니다. 이 WHERE vs HAVING을 읽으십시오 .


답변

Victor가 지적했듯이 문제는 별칭입니다. 그러나 표현식을 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 절이 평가 될 때 컬럼 값이 아직 결정되지 않았을 수 있습니다.

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

이렇게하면식이 복잡해질 때 반복되는 표현을 피할 수있어 코드를보다 쉽게 ​​관리 할 수 ​​있습니다.


답변

어쩌면 내 대답이 너무 늦었지만 다른 사람들을 도울 수 있습니다.

다른 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 절을 평가할 때 열 값이 아직 결정되지 않았기 때문에이 제한이 적용됩니다. 예를 들어, 다음 쿼리는 불법입니다.

ID를 선택하십시오. tbl_name에서 cnt를 기준으로 COUNT (*) cnt> 0 GROUP BY ID;