Oracle SQL: как использовать более 1000 элементов внутри предложения IN
У меня есть оператор SQL, где я хотел бы получить данные 1200 ep_codes
, используя предложение IN
. Когда я включаю более 1000 ep_codes
внутри предложения IN, Oracle говорит, что мне не разрешено это делать. Чтобы преодолеть это, я попытался изменить код SQL следующим образом:
SELECT period, ...
FROM my_view
WHERE period = '200912'
...
AND ep_codes IN (...1000 ep_codes...)
OR ep_codes IN (...200 ep_codes...)
Код был выполнен успешно, но результаты странные (результаты вычислений выбираются для всех периодов, а не только для 200912, что не то, что я хочу). Уместно ли это сделать с помощью OR
между предложениями IN
или я должен выполнить два отдельных кода как один с 1000, а другой с 200 ep_codes?
Решение Pascal Martin отлично работало. Спасибо всем, кто внес ценные предложения.
Ответы
Ответ 1
Не уверен, что использование большого количества значений в IN()
является хорошим, на самом деле - особенно для выступлений.
Когда вы говорите "результаты странные", может быть, это потому, что проблема с круглыми скобками? Что, если вы попробуете это, а не то, что вы предложили:
SELECT ...
FROM ...
WHERE ...
AND (
ep_codes IN (...1000 ep_codes...)
OR ep_codes IN (...200 ep_codes...)
)
Делают ли результаты менее странными?
Ответ 2
Рекомендуемый способ справиться с этим в Oracle - создать временную таблицу, записать в нее значения и присоединиться к ней. Использование динамически созданных предложений IN
означает, что оптимизатор запросов выполняет "жесткий анализ" каждого запроса.
create global temporary table LOOKUP
(
ID NUMBER
) on commit delete rows;
-- Do a batch insert from your application to populate this table
insert into lookup(id) values (?)
-- join to it
select foo from bar where code in (select id from lookup)
Ответ 3
На самом деле вы можете использовать коллекции/мультимножества здесь. Для их хранения вам понадобится тип таблицы номеров.
CREATE TYPE NUMBER_TABLE AS TABLE OF NUMBER;
...
SELECT *
FROM my_view
WHERE period MEMBER OF NUMBER_TABLE(1,2,3...10000)
Подробнее о мультисетах здесь:
Ответ 4
Похоже, что было бы лучшей идеей, как для производительности, так и для удобства обслуживания, для размещения кодов в отдельной таблице.
SELECT ...
FROM ...
WHERE ...
AND ep_code in (select code from ep_code_table)
Ответ 5
можете ли вы вставить значения 1200 ep_code
во временную таблицу, а затем INNER JOIN
в эту таблицу для фильтрации строк?
SELECT a.*
FROM mytable a
INNER JOIN tmp ON (tmp.ep_code = a.ep_code)
WHERE ...