Как выбрать список из 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 в электронной таблице или что-то еще. Если это так, то создать эти операторы выбора с помощью регулярных выражений очень просто. Просто вставьте колонку в редактор, который поддерживает поиск и замену регулярных выражений.