如何解决oracle 函数用于:从逗号分隔的字符串中选择不同的值计数
我需要一个 Oracle (11) 函数来处理这个问题。 我需要从逗号分隔的字符串中计算不同的值。
例如逗号分隔的字符串: 'Lorem,Ipsum,is,simply,dummy,text,Lorem,text'
结果必须是 = 6
因为
- 勒姆
- Ipsum
- 是
- 简单
- 假的
- 文字
我想这样使用
select fn_dist_count_values_in_list_arr('Lorem,text') from dual;
谁能帮忙写这个(“fn_dist_count_values_in_list_arr”)oracle函数?
解决方法
您不需要从 SQL 到 PL/SQL 函数的上下文切换,并且可以在 SQL 中完成所有操作:
SELECT ( SELECT COUNT( DISTINCT CAST(column_value AS VARCHAR2(20)) )
FROM XMLTABLE( ('"'||REPLACE(value,','","')||'"') ) )
AS num_distinct_values
FROM table_name
对于样本数据:
CREATE TABLE table_name ( value ) AS
SELECT 'Lorem,Ipsum,is,simply,dummy,text,Lorem,text' FROM DUAL;
输出:
| NUM_DISTINCT_VALUES | | ------------------: | | 6 |
如果你想要一个纯 PL/SQL 函数(这样你就没有多个上下文切换),那么:
CREATE FUNCTION fn_dist_count_values_in_list_arr (
list_value IN VARCHAR2
) RETURN NUMBER DETERMINISTIC
IS
TYPE t_words IS TABLE OF NUMBER(1,0) INDEX BY VARCHAR2(200);
v_words t_words;
v_start PLS_INTEGER := 1;
v_end PLS_INTEGER;
BEGIN
IF list_value IS NULL THEN
RETURN 0;
END IF;
LOOP
v_end := INSTR( list_value,v_start );
EXIT WHEN v_end = 0;
v_words(SUBSTR(list_value,v_start,v_end - v_start ) ) := 1;
v_start := v_end + 1;
END LOOP;
v_words(SUBSTR(list_value,v_start)) := 1;
RETURN v_words.COUNT;
END;
/
然后:
SELECT fn_dist_count_values_in_list_arr( value )
FROM table_name
输出:
| FN_DIST_COUNT_VALUES_IN_LIST_ARR(VALUE) | | --------------------------------------: | | 6 |
dbfiddle here
, CREATE OR REPLACE FUNCTION DIST_COUNT_VALUES_IN_STR_ARR
(STR_ARR IN VARCHAR2)
RETURN NUMBER
AS
DIST_COUNT NUMBER(38);
BEGIN
SELECT COUNT(DISTINCT COL1)
INTO DIST_COUNT FROM (
SELECT REGEXP_SUBSTR(STR_ARR,'[^,]+',1,LEVEL) COL1
FROM DUAL
CONNECT BY LEVEL <= REGEXP_COUNT(STR_ARR,') + 1
);
RETURN DIST_COUNT;
END;
这对我有用。内部查询通过在逗号字符上使用正则表达式将元素分隔成行。当我达到我的 Oracle 版本的对象名称的最大长度限制时,我不得不重命名您的函数。
,另一种方法是使用分层查询将逗号分隔值拆分为一组行(带子句)并对其运行简单的 sql 查询
with str_parsed as (SELECT REGEXP_SUBSTR('Lorem,text',LEVEL) val
FROM dual
CONNECT BY REGEXP_SUBSTR('Lorem,LEVEL) IS NOT NULL)
select count(distinct val) from str_parsed
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。