SQL-запрос для получения идентификаторов НЕ в таблице - PullRequest
5 голосов
/ 29 декабря 2011

Учитывая список идентификаторов, мне нужно определить те, которых нет в базе данных Oracle.Например, учитывая таблицу:

my_table

+----+-------+
| ID | DATA  |
+----+-------+
|  1 | Foo   |
+----+-------+
|  3 | Bar   |
+------------+
|  5 | Etc   |
+------------+

... и учитывая список [1, 2, 3, 4], мне нужен список[2, 4].

Я придумал этот синтаксис, используя предложение MINUS:

SELECT '1' as id FROM dual
UNION
SELECT '2' as id FROM dual
UNION
SELECT '3' as id FROM dual
UNION
SELECT '4' as id FROM dual
MINUS
SELECT id FROM my_table WHERE id IN ('1','2','3','4')

Но это кажется очень неуклюжим и быстро запутается, поскольку в действительности я буду иметь дело с сотнямиИдентификаторы одновременно. Есть ли лучший синтаксис для получения списка значений, чем синтаксис UNION?

Что-то вроде:

/* Pseudo code */
SELECT id FROM VALUES ('1', '2', '3', '4')
MINUS
SELECT id FROM my_table WHERE id IN ('1','2','3','4')

Другая альтернатива - сделать это программно,Я могу запросить базу данных для существующих идентификаторов.Затем в коде я могу удалить список найденных из исходного списка, чтобы получить подсписок тех, кого нет в базе данных.Это сработало бы, но я не прав, если бы база данных работала более эффективно?

Спасибо

Ответы [ 3 ]

4 голосов
/ 29 декабря 2011

Как объяснено здесь: Как как конвертировать csv-to-table-in-oracle , вы можете преобразовать свой список значений в таблицу.

После этоговсе просто:

select * from table(splitter('a,b,c,d'))
minus
select id from my_table;

или

select 
  column_value as id 
from table(splitter('a,b,c,d')) a
  left join my_table b on (a.column_value = b.id)
where b.id is null;
2 голосов
/ 29 декабря 2011

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

Передайте список как вложенную таблицу, а затем обработайте ее как реальную таблицу. Вы передаете список в виде массива из Java / Perl или любого другого языка, который вы используете для вызова хранимого процесса.

TYPE ID_ARRAY_T is TABLE of NUMBER;


PROCEDURE FIND_IDS_NOT_IN_LIST( i_list IN ID_ARRAY_T, o_output OUT SYS_REFCURSOR)
IS
v_id ID_ARRAY_T;
BEGIN
OPEN O_OUTPUT FOR
 SELECT column_value FROM TABLE(v_id) WHERE column_value 
   NOT IN (select ID from my_table);
END FIND_IDS_NOT_IN_LIST;
2 голосов
/ 29 декабря 2011

Как насчет этого:

SELECT * FROM dual WHERE id NOT IN (SELECT id FROM my_table);

или

SELECT * FROM dual WHERE id NOT EXISTS (SELECT id FROM my_table);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...