首页 > 解决方案 > oracle函数:从逗号分隔的字符串中选择不同的值计数

问题描述

我需要一个 Oracle (11) 函数来处理这个问题。我需要从逗号分隔的字符串中计算不同的值。

例如逗号分隔的字符串:'Lorem,Ipsum,is,simply,dummy,text,Lorem,Ipsum,is,simply,dummy,text,Lorem,Ipsum,is,simply,dummy,text'

结果必须是 = 6

由于

  1. 洛雷姆
  2. 伊普苏姆
  3. 简单地
  4. 假的
  5. 文本

我想这样使用

select fn_dist_count_values_in_list_arr('Lorem,Ipsum,is,simply,dummy,text,Lorem,Ipsum,is,simply,dummy,text,Lorem,Ipsum,is,simply,dummy,text') from dual;

任何人都可以帮助编写这个(“fn_dist_count_values_in_list_arr”)oracle函数吗?

标签: oraclefunctiondistinctdistinct-valuescsv

解决方案


您不需要从 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,Ipsum,is,simply,dummy,text,Lorem,Ipsum,is,simply,dummy,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 |

db<>在这里摆弄


推荐阅读