我正在为用户编写一个解决方案,该解决方案与他们针对客户数据库输入的电话号码列表相匹配。
用户需要输入逗号分隔的电话号码列表(整数),查询需要告诉用户列表中的哪些电话号码不在数据库中。
我能想到的唯一方法是首先创建一个NUMBER_LIST子集,其中包含我可以加入的所有电话号码,然后从我从客户数据库中带回来的那个列表中排除该列表。
WITH NUMBER_LIST AS (
SELECT INTEGERS
FROM (
SELECT level - 1 + 8000000000 INTEGERS
FROM dual
CONNECT BY level <= 8009999999-8000000000+1
)
WHERE INTEGERS IN (8001231001,8001231003,8001231234,8001231235,...up to 1000 phone numbers)
)
这里的问题是上面的代码可以很好地创建我的子集,数字在800-000-0000和800-999-9999之间。我的列表和客户数据库中的电话号码可以是任意范围(不仅仅是800个号码)。我这样做只是为了测试。从该查询生成子集大约需要6秒钟。如果我创建CONNECT BY LEVEL以包含从100-000-0000到999-999-9999的所有数字,这些数字正在运行我的查询内存以创建一个大的子集(我相信创建一个巨大的列表是荒谬的过度杀伤并使用我的IN语句将其分解。)
问题在于创建初始子集。我可以处理剩下的查询,但我需要能够生成数字子集,以便从我的IN语句中查询我的客户数据库。
要记住的事情很少:
如何在1000000000-9999999999(或所有美国10位数电话号码)之间的所有号码上使用此功能。生成我的初始巨型列表,然后排除除IN语句之外的所有内容,我可能会完全错误,但我不确定从何处开始。
非常感谢您的帮助。我从大家那里学到了很多东西。
答案 0 :(得分:3)
您可以使用以下内容:
SELECT *
FROM (SELECT regexp_substr(&x, '[^,]+', 1, LEVEL) phone_number
FROM dual
CONNECT BY LEVEL <= length(&x) - length(REPLACE(&x, ',', '')) + 1)
WHERE phone_number NOT IN (SELECT phone_table.phone_number
FROM phone_table)
第一个查询将构建一个包含各个电话号码的列表。
答案 1 :(得分:2)
这个问题与“我如何绑定列表”问题密切相关,这个问题已在这里出现过几次。我过去发过了一个答案Dynamic query with HibernateCritera API & Oracle - performance。
这样的事情应该做你想做的事情:
create table phone_nums (phone varchar2(10));
insert into phone_nums values ('12345');
insert into phone_nums values ('23456');
with bound_inlist
as
(
select
substr(txt,
instr (txt, ',', 1, level ) + 1,
instr (txt, ',', 1, level+1) - instr (txt, ',', 1, level) -1 )
as token
from (select ','||:txt||',' txt from dual)
connect by level <= length(:txt)-length(replace(:txt,',',''))+1
)
select *
from bound_inlist a
where not exists (select null from phone_nums where phone = token);
此处以逗号分隔的电话号码列表绑定到查询中,因此您正确使用绑定变量,并且您可以输入可能无限数量的电话号码以便一次性检查(尽管我会检查两者可以肯定的是4000和32767字符边界。
答案 2 :(得分:1)
如果你被约束到必须用IN (n1,n2,n3,...,n1000)
来解决,那么你的方法似乎是唯一的解决方案。
正如你所提到的,这是你预先创建的一个大清单。
您是否能够稍微调整您的方法?
WITH NUMBER_LIST (number) AS (
SELECT n1 FROM DUAL
UNION ALL SELECT n2 FROM DUAL
UNION ALL SELECT n3 FROM DUAL
...
UNION ALL SELECT n1000 FROM DUAL
)
答案 3 :(得分:1)
你说你不能使用临时表或过程或自定义函数 - 如果可以的话,这将是一项简单的任务。
用于提交此查询的客户端工具是什么?有没有理由不能查询数据库中的所有电话号码并在客户端进行比较?