Это проблема порядка операций: обратите внимание, мы материализуем результаты аналитики, используя производную таблицу, прежде чем отфильтруем ее.SELECT не выполняется до тех пор, пока не будет выполнено предложение where, поэтому псевдоним ERRCODE неизвестен предложению where.
Порядок операций SQL можно найти в Интернете, я не собираюсь пересматривать ;но в этом случае ниже приведены важные элементы / порядок.Вы заметите, что в ссылке конкретно указывается ваша проблема: оконные функции ... недоступны предложению WHERE, которое произошло до оценки оконной функции.
- FROM
- WHERE
- SELECT
Это означает, что предложение WHERE еще не знает о ERRCODE;так что это не может ограничивать это.Обычно это решается с помощью производной таблицы / встроенного представления или общего табличного выражения.
Вот встроенное представление / производная таблица:
INSERT INTO XE_ERR_RANG
SELECT Z.*
FROM (SELECT EMPLOYERID
, EMPLOYEEID
, lag(DECLARATIONPERIOD) over (ORDER BY DECLARATIONPERIOD) AS DECFROM
, DECLARATIONPERIOD AS DECTO
, lag(flag) over (ORDER BY DECLARATIONPERIOD) || flag AS ERRCODE
FROM XE_ERR_OVLP) Z
WHERE Z.ERRCODE in ('HS', 'SE');
Альтернативный подход с использованием общего табличного выражения (CTE):
Не проверено: но вы сказали, что Oracle 10g поддерживает CTE;но не рекурсия;так должно работать, если он поддерживает синтаксис вставки до CTE ...
INSERT INTO XE_ERR_RANG
WITH Z as (SELECT EMPLOYERID
, EMPLOYEEID
, lag(DECLARATIONPERIOD) over (ORDER BY DECLARATIONPERIOD) AS DECFROM
, DECLARATIONPERIOD AS DECTO
, lag(flag) over (ORDER BY DECLARATIONPERIOD) || flag AS ERRCODE
FROM XE_ERR_OVLP)
SELECT *
FROM Z
WHERE ERRCODE in ('HS', 'SE');