Понимание псевдонимов 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 уже выполняется.