我试图找到这个问题的解决方案已经有一段时间但没有成功,所以任何帮助都会非常感激。需要将ID列表与表进行比较,并找出存在哪些记录(及其中一个值)以及哪些记录不存在。
有一个ID列表,采用文本格式:
100,
200,
300
数据库表:
ID(PK) value01 value02 value03 .....
--------------------------------------
100 Ann
102 Bob
300 John
304 Marry
400 Jane
我需要的输出是:
100 Ann
200 missing or empty or whatever indication
300 John
明显的解决方案是创建表和连接,但我只有读访问权限(数据库是封闭的供应商产品,我只是一个用户)。编写PL / SQL函数似乎也很复杂,因为表有200多列和100k +记录,我没有运气创建动态数组记录。此外,要检查的ID列表包含数百个ID,我需要定期执行此操作,因此任何必须在单独的代码行中更改每个ID的解决方案都不会非常有用。 数据库是Oracle 10g。
答案 0 :(得分:1)
有许多内置的公共集合类型。你可以像这样利用其中一个:
with ids as (select /*+ cardinality(a, 1) */ column_value id
from table(UTL_NLA_ARRAY_INT(100, 200, 300)) a
)
select ids.id, case when m.id is null then '**NO MATCH**' else m.value end value
from ids
left outer join my_table m
on m.id = ids.id;
要查看数据库中的公共类型列表,请运行:
select owner, type_name, coll_type, elem_type_name, upper_bound, precision, scale from all_coll_types
where elem_type_name in ('FLOAT', 'INTEGER', 'NUMBER', 'DOUBLE PRECISION')
提示
/*+ cardinality(a, 1) */
只是用于告诉oracle我们的数组中有多少个元素(如果没有指定,默认将是8k元素的假设)。只需设置一个相当准确的数字。
答案 1 :(得分:0)
您可以使用CONNECT BY
将变量转换为查询(在11g上测试,应该在10g +上工作):
SQL> WITH DATA AS (SELECT '100,200,300' txt FROM dual)
2 SELECT regexp_substr(txt, '[^,]+', 1, LEVEL) item FROM DATA
3 CONNECT BY LEVEL <= length(txt) - length(REPLACE(txt, ',', '')) + 1;
ITEM
--------------------------------------------
100
200
300
然后,您可以将此结果加入表格,就像它是标准视图一样:
SQL> WITH DATA AS (SELECT '100,200,300' txt FROM dual)
2 SELECT v.id, dbt.value01
3 FROM dbt
4 RIGHT JOIN
5 (SELECT to_number(regexp_substr(txt, '[^,]+', 1, LEVEL)) ID
6 FROM DATA
7 CONNECT BY LEVEL <= length(txt) - length(REPLACE(txt, ',', '')) + 1) v
8 ON dbt.id = v.id;
ID VALUE01
---------- ----------
100 Ann
300 John
200
答案 2 :(得分:0)
解决此问题的一种方法是动态创建一个公用表表达式,然后可以将其包含在查询中。你要瞄准的最终synatx是:
with list_of_values as (
select 100 val from dual union all
select 200 val from dual union all
select 300 val from dual union all
...)
select
lov.val,
...
from
list_of_values lov left outer join
other_data t on (lov.val = t.val)
它不是很优雅,特别是对于大型值集,但与您可能没有特权的数据库的兼容性非常好。