Понимание псевдонимов Oracle-Почему псевдоним не распознается в запросе, если он не завернут во второй запрос?
у меня есть запрос
SELECT COUNT(*) AS "CNT",
imei
FROM devices
, который выполняет просто отлично. Я хочу дополнительно ограничить запрос инструкцией WHERE. Следующим (человеческим) логическим шагом является изменение запроса следующим образом:
SELECT COUNT(*) AS "CNT",
imei
FROM devices
WHERE CNT > 1
однако это приводит к сообщению об ошибке ORA-00904: "CNT": недопустимый идентификатор. По какой-то причине обертывание запроса в другой запрос приводит к желаемому результату:
SELECT *
FROM (SELECT COUNT(*) AS "CNT",
imei
FROM devices
GROUP BY imei)
WHERE CNT > 1
почему Oracle не распознает псевдоним "CNT" в второй вопрос?
4 ответов
самый простой ответ заключается в том, что определяет, какой столбец будет вызываться в результате, который отличается от области самого запроса.
в вашем примере, используя HAVING
предложение будет работать лучше всего:
SELECT COUNT(*) AS "CNT",
imei
FROM devices
GROUP BY imei
HAVING COUNT(*) > 1
потому что документация приложения:
укажите псевдоним для столбца выражение. База данных Oracle будет использовать этот псевдоним в заголовке столбца результирующий набор. Ключевое слово AS необязательный. Псевдоним эффективно переименовывает элемент списка выбора для продолжительность запроса. Псевдоним может использоваться в order_by_clause но не другие предложения в запросе.
однако, когда у вас есть внутренний выбор, то есть например, создание встроенного представления, в котором псевдонимы столбцов вступают в силу, поэтому вы можете использовать его на внешнем уровне.
Я бы предположил, потому что псевдоним не присваивается столбцу результата до тех пор, пока предложение WHERE не будет обработано и сгенерированы данные. Отличается ли Oracle от других СУБД в этом поведении?
подводя итог, этот маленький драгоценный камень объясняет:
10 простых шагов к полному пониманию SQL
общим источником путаницы является тот простой факт, что синтаксис SQL элементы не упорядочены так, как они выполняются. Лексико заказ:
SELECT [ DISTINCT ] FROM WHERE GROUP BY HAVING UNION ORDER BY
для простоты перечислены не все предложения SQL. Этот лексический порядок принципиально отличается от логического порядка, т. е. исполнение:
FROM WHERE GROUP BY HAVING SELECT DISTINCT UNION ORDER BY
как следствие, все, что вы помечаете с помощью "как", будет доступно только после WHERE
, HAVING
и GROUP BY
уже выполняется.