Использование псевдонима столбца в предложении WHERE запроса MySQL вызывает ошибку

Запрос, который я запускаю, выглядит следующим образом, однако я получаю эту ошибку:

# 1054 - Неизвестный столбец "secure_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'
 )
)

Мой вопрос: почему я не могу использовать поддельный столбец в предложении where того же запроса БД?

Ответ 1

Вы можете использовать только псевдонимы столбцов в предложениях GROUP BY, ORDER BY или HAVING.

Стандартный SQL не позволяет вам обратитесь к псевдониму столбца в ГДЕ пункт. Это ограничение наложено потому что, когда код WHERE Выполнено, значение столбца может еще не определяется.

Скопировано из Документация по MySQL

Как указано в комментариях, использование HAVING вместо этого может выполнять работу. Не забудьте прочитать здесь WHERE vs HAVING.

Ответ 2

Как отметил Виктор, проблема связана с псевдонимом. Однако этого можно избежать, поставив выражение непосредственно в предложение 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'
 )
)

Однако, я думаю, это очень неэффективно, так как подзапрос должен выполняться для каждой строки внешнего запроса.

Ответ 3

Стандартный 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'
 )
)

Это позволяет избежать повторения выражения, когда оно усложняется, что упрощает работу с кодом.

Ответ 4

Возможно, мой ответ слишком поздний, но это может помочь другим.

Вы можете заключить его в другой оператор select и использовать в нем предложение where.

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

calcAlias ​​- это вычисляемый столбец псевдонимов.

Ответ 5

Вы можете использовать предложение HAVING для фильтра, рассчитанного в полях SELECT и псевдонимах

Ответ 6

Я использую 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'
 )
)

Ответ 7

Стандартный SQL запрещает ссылки на псевдонимы столбцов в предложении WHERE. Это ограничение наложено, потому что, когда вычисляется предложение WHERE, значение столбца может еще не определено. Например, следующий запрос является незаконным:

SELECT id, COUNT (*) AS cnt FROM tbl_name WHERE cnt > 0 GROUP BY id;