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

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

Можно ли в oracle выделить весь этот список из таблицы DUAL? Что-то типа:

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

person barker    schedule 15.12.2016    source источник
comment
А что насчет оператора BETWEEN?   -  person cha    schedule 15.12.2016
comment
Нигде не сказано, что это непрерывные числа. Фактически образец показывает полностью случайные числа   -  person Nick.McDermaid    schedule 15.12.2016
comment
Вы также можете попробовать IN (SELECT C1 FROM (SELECT 'id123' C1 FROM DUAL UNION ALL SELECT 'id8923' FROM DUAL UNION ALL SELECT 'id32983' FROM DUAL))   -  person Nick.McDermaid    schedule 15.12.2016
comment
Теплый совет: попросите временную базу данных, в которой вы можете создавать и заполнять свои собственные таблицы.   -  person David דודו Markovitz    schedule 15.12.2016
comment
Откуда вы берете эти 10000 идентификаторов? Разве это не результат другого запроса? Может быть, это список всех идентификаторов, за исключением нескольких?   -  person Marcin Wroblewski    schedule 15.12.2016
comment
они отметили мой вопрос как дубликат, но я нигде не могу найти этот вопрос в Google. Спасибо за совет всем   -  person barker    schedule 15.12.2016


Ответы (4)


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

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

SYS.ODCIVARCHAR2LIST и SYS.ODCINUMBERLIST - это типы коллекций, которые включены в схему SYS.

Вы можете присоединиться к этой таблице напрямую, SELECT из какой таблицы вы 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'
                    );

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

person MT0    schedule 15.12.2016
comment
Добавлена ​​некоторая информация о доступных типах коллекций ODCI. Надеюсь, все в порядке. тобой - person David דודו Markovitz; 15.12.2016
comment
никогда раньше не видел этот sys.odc, но он работает. Спасибо, приятель :) - person barker; 15.12.2016
comment
@DuduMarkovitz Хотя информация, возможно, была интересной, она в основном не имела отношения к ответу на вопрос, и не было сопроводительного объяснения, связанного с кодом и списком (да, я понял это и его актуальность, но большинство людей, плохо знакомых с коллекциями, могут не знать) - было бы лучше, если бы вы объяснили это правильно в своем собственном ответе или написали страницу документации о встроенных типах коллекций. - person MT0; 16.12.2016
comment
Я намеревался вернуться к нему и завершить его. Думаю, важно, чтобы определения коллекций были известны (количество максимальных элементов и типы элементов) - person David דודו Markovitz; 16.12.2016
comment
P.s. почему используется старый синтаксис соединения (table1, table2) вместо ANSI / ISO JOIN? - person David דודו Markovitz; 16.12.2016

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);
person a_horse_with_no_name    schedule 15.12.2016
comment
Ух ты. Как вы пришли к обходному пути с несколькими столбцами? Любая документация / официальная ссылка / полуофициальная ссылка? - person David דודו Markovitz; 15.12.2016
comment
@DuduMarkovitz: нет, у меня нет ссылки на это. - person a_horse_with_no_name; 15.12.2016
comment
Можете ли вы вспомнить, где и когда вы его впервые увидели? - person David דודו Markovitz; 15.12.2016
comment
@DuduMarkovitz: Я видел это здесь, на SO - person a_horse_with_no_name; 15.12.2016
comment
Сделал быстрый поиск и добавил ссылку на свой ответ. Надеюсь, все в порядке. тобой. - person David דודו Markovitz; 15.12.2016
comment
вау, какая странная вещь, я думаю, я мог бы написать функцию в Excel, чтобы эта работа работала, такой отличный ответ! в конце концов, я обернул первый ответ Марковица внутри оператора with () и все пошло гладко :) - person barker; 15.12.2016

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

person APC    schedule 15.12.2016

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

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 ...
person David דודו Markovitz    schedule 15.12.2016