Как выбрать список из 10000 уникальных идентификаторов из двойного в Oracle SQL

Поэтому я не могу создавать или редактировать таблицы (я пользователь с правами только на чтение) и хочу найти 10000 уникальных идентификаторов. Я не могу поместить их в оператор IN(), потому что оракул ограничивает более 1000 элементов.

Можно ли выбрать весь этот список из таблицы ДВОЙНОЙ в оракуле? Что-то вроде:

select  
'id123,id8923,id32983,id032098,id308230,id32983289'  
from DUAL

4 ответа

Решение

Используйте коллекцию (они не ограничены 1000 предметов, таких как IN пункт есть):

SELECT COLUMN_VALUE AS id
FROM   TABLE(
         SYS.ODCIVARCHAR2LIST(
           'id123', 'id8923', 'id32983', 'id032098', 'id308230', 'id32983289'
         )
       )

SYS.ODCIVARCHAR2LIST а также SYS.ODCINUMBERLIST типы коллекций, которые поставляются в SYS схемы.

Вы можете присоединиться к этому непосредственно к любой таблице SELECTбез необходимости использовать DUAL Таблица:

SELECT y.*
FROM   your_table y,
       TABLE(
         SYS.ODCIVARCHAR2LIST(
           'id123', 'id8923', 'id32983', 'id032098', 'id308230', 'id32983289'
         )
       ) i
WHERE  y.id = i.COLUMN_VALUE;

Если вы можете создать тип коллекции, то вам даже не нужно TABLE выражение и может использовать его непосредственно в WHERE пункт с использованием MEMBER OF оператор:

CREATE OR REPLACE TYPE stringlist IS TABLE OF VARCHAR2(200);
/

SELECT *
FROM   yourtable
WHERE  id MEMBER OF stringlist(
                      'id123', 'id8923', 'id32983', 'id032098', 'id308230', 'id32983289'
                    );

Вы даже можете передать значения в качестве параметра связывания - см. Мой ответ здесь

Oracle по-прежнему не поддерживает VALUES конструктор строки, поэтому есть только два уродливых обходных пути:

Ограничение в 1000 единиц не применяется для условий IN с несколькими столбцами.

Списки выражений

Список выражений через запятую может содержать не более 1000 выражений. Список наборов выражений через запятую может содержать любое количество наборов, но каждый набор может содержать не более 1000 выражений.

так что вы можете сделать:

where (1,id) in ( (1,'id123'),
                  (1,'id8923'),
                  (1,'id32983'), 
                  (1,'id032098'), .... )

Или с помощью большого уродливого UNION ALL:

with idlist (xid) as (
  select 'id123' from dual union all 
  select 'id8923' from dual union all 
  .....
  select 'id32983' from dual 
)
select ...
from some_table
where id in (select xid from idlist);

Еще один обходной путь

select  *

from    t

where   id in ('id1','id2','id3',...,'id1000')
     or id in ('id1001','id1002','id1003',...,'id2000')
     or id in ('id2001','id2002','id2003',...,'id3000')
     or ...

Одним из решений является предложение WITH:

with ids as (
   select 'id123' as uid from dual union all
   select 'id8923' as uid from dual union all
   select 'id32983' as uid from dual union all
   select 'id032098' as uid from dual union all
   select 'id308230' as uid from dual union all
   select 'id32983289' as uid from dual 
)
select *
from ids
     join your_table yt
     on yt.id = ids.uid  

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

Другие вопросы по тегам