鉴于ID列表,我需要确定那些不在Oracle数据库中的ID。例如,给出表:
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')
但这看起来非常笨拙并且会很快变得混乱,因为实际上我将同时处理数百个ID。 获取值列表比使用UNION语法有更好的语法吗?
产生效果:
/* Pseudo code */
SELECT id FROM VALUES ('1', '2', '3', '4')
MINUS
SELECT id FROM my_table WHERE id IN ('1','2','3','4')
另一种选择是以编程方式进行。我可以在数据库中查询现有ID。然后在代码中我可以删除原始列表中找到的列表,以获取那些不在数据库中的列表。这可行,但我不正确让数据库做这项工作会更有效吗?
由于
答案 0 :(得分:4)
如此处所述:如何how-to-convert-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;
答案 1 :(得分:2)
这个怎么样:
SELECT * FROM dual WHERE id NOT IN (SELECT id FROM my_table);
或
SELECT * FROM dual WHERE id NOT EXISTS (SELECT id FROM my_table);
答案 2 :(得分:2)
我没有方便测试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;