내가 실행중인 쿼리는 다음과 같지만이 오류가 발생합니다.
# 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;