当字段内有逗号分隔时,Oracle如何对这些字段值进行分组

CREATE  TABLE  info (

    users    varchar(100)

);



INSERT INTO info VALUES('userA@userB@userC');

INSERT INTO info VALUES('userB@userC@userD');

INSERT INTO info VALUES('userC@userD@userE');







COLUMN "用户" FORMAT A15





SELECT

  to_char(strvalue) as "用户",

  count(*) AS "用户数"

FROM

  info,

  table(fn_split( info.users,  '@'))

GROUP BY

  to_char(strvalue)

ORDER BY

  1;





用户                用户数

--------------- ----------

userA                    1

userB                    2

userC                    3

userD                    2

userE                    1
Oracle 需要首先在数据库中, 创建好 类型 与 函数。

来实现一个  split 功能的处理。







-- 定义一个对象类型.

CREATE OR REPLACE TYPE ty_row_str_split as object (strValue VARCHAR2 (4000));

/



-- 定义一个 表/数组类型, 内容是前面定义的那个对象.

CREATE OR REPLACE TYPE ty_tbl_str_split IS TABLE OF ty_row_str_split;

/



--------------------

-- 字符分割函数.

-- 参数1:  被分割的源字符串

-- 参数2:  用于拆分的字符串。

--------------------

CREATE OR REPLACE FUNCTION fn_split(

  p_str       IN VARCHAR2,

  p_delimiter IN VARCHAR2)

RETURN ty_tbl_str_split IS

  j         INT := 0;

  i         INT := 1;

  -- 被分割的源字符串 的长度.

  len       INT := 0;

  -- 分隔字符串的长度

  len1      INT := 0;

  -- 暂存的中间每一个单元的文本信息.

  str       VARCHAR2(4000);

  -- 预期返回结果.

  str_split ty_tbl_str_split := ty_tbl_str_split();

BEGIN

  -- 被分割的源字符串 的长度.

  len   := LENGTH(p_str);

  -- 分隔字符串的长度.

  len1 := LENGTH(p_delimiter);



  -- 遍历 被分割的源字符串.

  WHILE j < len LOOP

    -- 在被分割的源字符串中, 查询 分隔字符串.

    j := INSTR(p_str, p_delimiter, i);



    IF j = 0 THEN

      -- j=0 意味着没有找到.

      -- 可以理解为是查询到最后一个单元了.

      -- 设置 j := len, 让外部的循环处理可以结束了.

      j  := len;

      -- 获取最后一个单元的内容.

      str := SUBSTR(p_str, i);

      -- 结果追加一行.

      str_split.EXTEND;

      -- 设置结果内容.

      str_split(str_split.COUNT) := ty_row_str_split(strValue => str);



      IF i >= len THEN

        EXIT;

      END IF;

    ELSE

      -- 如果在被分割的源字符串中,找到了 分隔字符串.

      -- 首先,获取分割的内容.

      str := SUBSTR(p_str, i, j - i);

      -- 然后设置索引, 下一次再查找的时候,从指定的索引位置开始(不是从0开始找了)

      i := j + len1;

      -- 结果追加一行.

      str_split.EXTEND;

      -- 设置结果内容.

      str_split(str_split.COUNT) := ty_row_str_split(strValue => str);

    END IF;

  END LOOP;





  RETURN str_split;

END fn_split;

/









函数创建完毕以后,可以开始做查询的处理.





SQL> select to_char(strvalue) as Value from table(fn_split('aa,bb,cc',','));



VALUE

-------------------------------------------------------------------------------

aa

bb

cc

 

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页