Нечетное поведение 'UNION' в запросе Oracle SQL - PullRequest
2 голосов
/ 23 апреля 2010

Вот мой запрос:

SELECT my_view.*
FROM my_view
WHERE my_view.trial in (select 2 as trial_id from dual union select 3 from dual union select 4 from dual)
and my_view.location like ('123-%')

Когда я выполняю этот запрос, он возвращает результаты, которые не соответствуют условию my_view.location like ('123-%'). Как будто это условие полностью игнорируется. Я даже могу изменить его на my_view.location IS NULL, и он выдаст те же результаты, несмотря на то, что это поле не имеет значения NULL.

Я знаю, что этот запрос кажется нелепым с выбором из двойного, но я структурировал его таким образом, чтобы воспроизвести проблему, возникающую у меня, когда я использую предложение WITH (в результате этого запроса выбираются два встроенных слова вид есть).

Я могу изменить запрос следующим образом, и он выдаст ожидаемые результаты:

SELECT my_view.*
FROM my_view
WHERE my_view.trial in (2, 3, 4)
and my_view.location like ('123-%')

К сожалению, я не знаю пробные значения заранее (они запрашиваются в предложении WITH), поэтому я не могу структурировать свой запрос таким образом. Что я делаю не так?

Я скажу, что представление my_view состоит из 3 других представлений, результаты которых UNION ALL, и каждое из которых извлекает некоторые данные по ссылке в БД. Не то, чтобы я считаю, что это должно иметь значение, но в случае, если это имеет значение.

Ответы [ 3 ]

1 голос
/ 23 апреля 2010

Одна вещь, которую вы можете попробовать, если вам не повезло с этим маршрутом, это заменить «IN» на оператор «EXISTS» или «NOT EXISTS».

Если бы вы могли выполнять то, что вы хотите, используя объединения, это было бы лучшим вариантом из-за производительности. Если у вас есть представления, извлекающие данные из представлений, вы часто можете сделать один запрос, чтобы выполнить то, что вам нужно, что повысит производительность с помощью подзапросов.

1 голос
/ 24 апреля 2010

Если вы делаете

EXPLAIN PLAN FOR 
SELECT my_view.*
FROM my_view
WHERE my_view.trial in (select 2 as trial_id from dual union select 3 from dual union select 4 from dual)
and my_view.location like ('123-%');
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);

вы должны увидеть, где предикат местоположения равен 9 или не применяется). Держу пари, что это как-то связано со ссылками на БД, и вы не сможете воспроизвести его, если все таблицы являются локальными.

Оптимизация распределенного запроса становится сложной.

0 голосов
/ 23 апреля 2010

Попробуйте изменить запрос UNION для использования UNION ALL, например:

SELECT my_view.* 
FROM my_view 
WHERE my_view.trial in (select 2 as trial_id from dual
                        UNION ALL
                        select 3 AS TRIAL_ID from dual
                        UNION ALL
                        select 4 AS TRIAL_ID from dual) 
and my_view.location like ('123-%') 

Я также добавил "AS TRIAL_ID" в 3 и 4 случаях. Я согласен, что ни один из них не должен иметь значения, но я иногда сталкивался со случаями, когда вещи, которые, по моему мнению, не должны иметь значения, имели значение.

Удачи.

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