Запрос UNION ALL в Oracle приводит к ошибке - PullRequest
1 голос
/ 31 марта 2020

Я не могу понять, почему я получаю это сообщение об ошибке в Oracle. Пожалуйста, смотрите сообщение об ошибке ниже. Я использую UNION ALL, и оба запроса работают (верхний и нижний).

Кроме того, оба запроса имеют одинаковые заголовки. Итак, я не уверен, почему этот союз все не работает и получает сообщение об ошибке. Я продолжаю пытаться понять это, но я никуда не денусь.

Сообщение об ошибке

ORA-00933: SQL command not properly ended
Error at Line: 13 Column: 23

Код

select a.ID1, a.ID2, cnt, a.*, b.*
from (
select t.*, 
count(distinct ID1) over(partition by ID2) cnt 
from TABLE1 t) a
, TABLE2 b 
where a.cnt > 1
and a.ID1=b.ID1 (+)
and (b.STATUS in ('A','L','P','S') 
or b.DATE1 >= TO_DATE('2018-01-01','YYYY-MM-DD'))
order by a.ID2 asc
union all
select a.ID1, a.ID2, cnt, a.*, j.*
from (
select t.*, 
count(distinct ID1) over(partition by ID2) cnt 
from TABLE1 t) a
inner join TABLE2 j
on a.ID1=j.ID1
inner join SCHEMA.TABLE3 d
on j.ALTER_ID1=d.ALTER_ID1
where a.cnt > 1
order by a.ID2 asc

Ответы [ 2 ]

3 голосов
/ 31 марта 2020

Вы заказываете общий набор результатов, а не каждую ветвь объединения; поэтому вам нужно избавиться от первого order by предложения:

...
or b.DATE1 >= TO_DATE('2018-01-01','YYYY-MM-DD'))
union all
select a.ID1, a.ID2, cnt, a.*, j.*
...
order by ID2 asc

Это упоминается в документации :

Вы не можете указать order_by_clause в подзапросе этих операторов.


Кстати, если вы предоставляете фиксированные даты, вы можете использовать литералы даты , которые немного меньше набрав:

or b.DATE1 >= DATE '2018-01-01')

И, как указал @Littlefoot, в этом предложении order-by будет выбрано «ORA-00960: неоднозначное именование столбцов в списке выбора», поскольку у вас есть a.ID1, a.ID2, ... a.*, что означает ID1 и ID2 столбцы появятся дважды в списке выбора, и Oracle не знает, какую ссылку ID1 вы имеете в виду (здесь они имеют одинаковое значение, но не обязательно). Не рекомендуется использовать .* - намного лучше перечислять столбцы, которые вам действительно нужны.

Также плохая идея смешивать объединения ANSI (как во второй ветви) с соединениями старого стиля ( как в вашей первой ветке); Вы можете сойти с рук здесь, но это может сбить с толку оптимизатора, как и любого другого, кто смотрит на код, и даже это может когда-нибудь сломаться. Вы использовали (+), но не всегда, так что в любом случае это будет внутренним соединением; но если вы хотите внешнее соединение, запишите его как правильное ANSI.

0 голосов
/ 31 марта 2020

Попробуйте использовать order by только в конце последнего запроса и удалите его из первого при объединении всех.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...