Любопытная проблема с Oracle UNION и ORDER BY
следующий запрос прекрасно действует практически в каждой базе данных (или dual
фиктивная таблица), включая Oracle:
select 'A' as x from dual union all
select 'B' from dual
order by x asc
возвращение:
| X |
|---|
| A |
| B |
теперь этот запрос по-прежнему довольно стандартный SQL, но не работает на Oracle
select 'A' as x from dual union all
select 'B' from dual union all
select 'C' from dual
order by x asc
Я
ORA-00904: "X": invalid identifier
это, однако, работает:
select 'A' as x from dual union all
select 'B' as x from dual union all
select 'C' from dual
order by x asc
Я играл с этой проблемой и выяснил, что, по-видимому, по крайней мере, первый подселект и второй-последний (??) subselect должен иметь столбец с именем x
. В первом примере две подвыборки, казалось просто совпадают. пример:
select 'A' as x from dual union all
select 'B' from dual union all
select 'C' from dual union all
select 'D' from dual union all
select 'E' from dual union all
select 'F' as x from dual union all
select 'G' from dual
order by x asc
как вы могли догадаться, это не работает:
select 'A' as x from dual union all
select 'B' from dual union all
select 'C' from dual union all
select 'D' from dual union all
select 'E' as x from dual union all
select 'F' from dual union all
select 'G' from dual
order by x asc
интересная сторона-Примечание:
производные таблицы, похоже, не страдают от этого ограничения. этот работает:
select * from (
select 'A' as x from dual union all
select 'B' from dual union all
select 'C' from dual
)
order by x asc
вопрос:
это (известный?) ошибка в синтаксическом анализаторе Oracle SQL, или есть какая-либо очень тонкая деталь в синтаксисе языка, которая абсолютно требует первого и Второго последнего подселекта для хранения столбца имени, на который ссылается ORDER BY
предложения?
2 ответов
это на самом деле не отвечает на вопрос, но, похоже, это ошибка парсера (или "функция"), а не языковое требование.
согласно моей поддержке Oracle, это, похоже, было поднято как ошибка 14196463, но закрыто без разрешения. Это также упоминается в сообщество thread 3561546. Вам нужна учетная запись MOS или, по крайней мере, учетная запись Oracle, чтобы увидеть любой из них.
это также обсуждалось в потоке OTN что насколько я могу судить, требуется базовый логин Oracle, а не учетная запись MOS. Это также не имеет большой информации, но повторяет ваши выводы, а также предполагает, что поведение существовало по крайней мере до 9.2.0.8 и, возможно, намного раньше.
документация немного расплывчато, но не указывает, что это, как ожидается, будет проблемой:
для составных запросов, содержащих операторы set
UNION
,INTERSECT
,MINUS
илиUNION ALL
наORDER BY
предложение должно указывать позиции или псевдонимы, а не явные выражения. Кроме того,ORDER BY
предложение может появиться только в последнем запросе компонента. TheORDER BY
предложение упорядочивает все строки, возвращаемые всем составным запросом.
вы сглаживаете свое выражение и используете его, и он не говорит, что вам нужно псевдоним конкретных компонентов (хотя, конечно, он не говорит вам не придется либо).
поведение кажется несовместимым с псевдоним действителен для окончательной проекции, и обычное правило о том, что псевдоним действителен только в предложении order by - это, кажется, падает где-то посередине.
Это не отвечает, почему вы получаете несогласованное поведение из своего текущего запроса, но в Oracle вы можете легко переписать как следующее (что никогда не должно завершиться ошибкой недопустимого идентификатора):
with t(x) as (
select 'A' from dual
union all
select 'B' from dual
union all
select 'C' from dual
)
select * from t
order by x asc
с дополнительным бонусом, который вы указываете только псевдоним столбца (x) один раз.