列中的子字符串

时间:2016-12-09 20:30:29

标签: sql oracle oracle11g

我有一个列有几个项目,我需要计算它被调用的次数,我的列表看起来像这样:

Table Example

Id_TR               Triggered
--------------      ------------------
A1_6547             R1:23;R2:0;R4:9000
A2_1235             R2:0;R2:100;R3:-100
A3_5436             R1:23;R2:100;R4:9000
A4_1245             R2:0;R5:150

我希望结果如下:

Expected Results

Triggered          Count(1)
---------------    --------
R1:23               2
R2:0                3
R2:100              2
R3:-100             1
R4:9000             2
R5:150              1

我试图做一些子串,但似乎无法找到如何解决这个问题。有人可以帮忙吗?

4 个答案:

答案 0 :(得分:1)

这仅用于学习目的 检查我的其他解决方案

性能:每秒1K记录

select      x.triggered
           ,count(*)

from        t
           ,xmltable 
            (
                '/r/x'
                passing xmltype('<r><x>' || replace(triggered,';', '</x><x>') || '</x></r>')
                columns triggered varchar(100) path '.'
            ) x

 group by   x.triggered
 ;

答案 1 :(得分:1)

with x as (
   select listagg(Triggered, ';') within group (order by Id_TR) str from table
)
select regexp_substr(str,'[^;]+',1,level) element, count(*)
  from x
  connect by level <= length(regexp_replace(str,'[^;]+')) + 1
  group by regexp_substr(str,'[^;]+',1,level);

首先使用triggeredlistagg的所有值连接到一个列表中,然后解析它并执行group by

解析列表的另一种方法是herehere

答案 2 :(得分:1)

此解决方案比CONNECT BY解决方案快X3倍

性能:每秒15K记录

with        cte (token,suffix)
            as 
            (
                select      substr(triggered||';',1,instr(triggered,';')-1)     as token
                           ,substr(triggered||';',instr(triggered,';')+1)       as suffix

                from        t

                union all

                select      substr(suffix,1,instr(suffix,';')-1)     as token
                           ,substr(suffix,instr(suffix,';')+1)       as suffix

                from        cte

                where       suffix is not null

            )

 select     token,count(*)
 from       cte
 group by   token
 ;          

答案 3 :(得分:0)

这是一个公平的解决方案。

性能:每秒5K记录

select      triggered
           ,count(*)            as cnt 

from       (select      id_tr
                       ,regexp_substr(triggered,'[^;]+',1,level) as triggered

            from        t

            connect by      id_tr  = prior id_tr
                        and level <= regexp_count(triggered,';')+1
                        and prior sys_guid() is not null
            ) t

group by    triggered
;