我有一个包含100个逗号分隔数字的列表,我需要找到哪些数字在列表中但不在(从some_table中选择some_value)....类似于2之间选择的减号...是否有直接的方式来做到这一点。 我正在使用oracle 12g
答案 0 :(得分:2)
您可以使用XMLTable()
将数字字符串列表转换为
select to_number(x.column_value) from xmltable('1,3,5,7,9') x
where not exists (
select some_value from some_table where some_value = to_number(x.column_value)
);
或如果some_value
未被编入索引,则减号可能更有效:
select to_number(column_value) from xmltable('1,3,5,7,9')
minus
select some_value from some_table;
字符串列表作为XQuery expression处理,或者更具体地说是XQuery序列:
逗号(,)构造函数创建序列。序列操作函数,例如并集和交叉也是可用的。所有XQuery序列都是有效的平面:嵌套序列被视为其扁平等价物。因此,例如,(1,2,(3,4,(5),6),7)被视为(1,2,3,4,5,6,7)。单例序列(如(42))在大多数XQuery上下文中的作用与单个项目42相同。请记住,任何XQuery表达式的结果都是一个序列。
快速演示:
with some_table(some_value) as (
select 1 from dual
union all select 7 from dual
)
select to_number(x.column_value) from xmltable('1,3,5,7,9') x
where not exists (
select some_value from some_table where some_value = to_number(x.column_value)
);
TO_NUMBER(X.COLUMN_VALUE)
---------------------------------------
5
3
9
答案 1 :(得分:1)
您可以将字符串拆分为集合:
Oracle安装程序:
CREATE OR REPLACE TYPE numberlist IS TABLE OF NUMBER;
/
CREATE OR REPLACE FUNCTION split_Number_List(
i_str IN VARCHAR2,
i_delim IN VARCHAR2 DEFAULT ','
) RETURN numberlist DETERMINISTIC
AS
p_result numberlist := numberlist();
p_start NUMBER(5) := 1;
p_end NUMBER(5);
c_len CONSTANT NUMBER(5) := LENGTH( i_str );
c_ld CONSTANT NUMBER(5) := LENGTH( i_delim );
BEGIN
IF c_len > 0 THEN
p_end := INSTR( i_str, i_delim, p_start );
WHILE p_end > 0 LOOP
p_result.EXTEND;
p_result( p_result.COUNT ) := TO_NUMBER( SUBSTR( i_str, p_start, p_end - p_start ) );
p_start := p_end + c_ld;
p_end := INSTR( i_str, i_delim, p_start );
END LOOP;
IF p_start <= c_len + 1 THEN
p_result.EXTEND;
p_result( p_result.COUNT ) := TO_NUMBER( SUBSTR( i_str, p_start, c_len - p_start + 1 ) );
END IF;
END IF;
RETURN p_result;
END;
/
<强>查询强>:
SELECT COLUMN_VALUE FROM TABLE( split_Number_List( '1,2,3,5,8,13,21' ) )
MINUS
SELECT id FROM your_table
查询2 :
或者,您可以使用正则表达式:
SELECT TO_NUMBER( REGEXP_SUBSTR( '1,2,3,5,8,13,21', '\d+', 1, LEVEL ) )
FROM DUAL
CONNECT BY LEVEL <= REGEXP_COUNT( '1,2,3,5,8,13,21', '\d+' )
MINUS
SELECT id FROM your_table