计算一个字段结果中的字符串出现次数-Oracle 11

时间:2018-07-04 16:24:22

标签: oracle11g aggregate

我想要的是通过这种方式来计算字符串的出现次数:

ID | NAME | ITEMS
1  | JFK  | 100/100/100/200/300/300

我想把它变成

ID | NAME | ITEMS
1  | JFK  | 100(3),200(1),300(2)

一个功能会很好,但是如果可以在SELECT内完成,那就太棒了。

我正在使用Oracle 11,但是如果您能提供通用的产品,可能会帮助更多的人。

谢谢:)

1 个答案:

答案 0 :(得分:1)

这有点冗长,但是您可以将字符串标记为单独的行:

select id, name, regexp_substr(items, '(.*?)(/|$)', 1, level, null, 1) as item
from your_table
connect by level < regexp_count(items, '(.*?)(/|$)')
and prior id = id
and prior dbms_random.value is not null;

然后按项目分组以获取计数:

select id, name, item, count(*) as item_count
from (
  select id, name, regexp_substr(items, '(.*?)(/|$)', 1, level, null, 1) as item
  from your_table
  connect by level < regexp_count(items, '(.*?)(/|$)')
  and prior id = id
  and prior dbms_random.value is not null
)
group by id, name, item;

,然后再次按ID和名称进行分组,以汇总回单个字符串:

select id, name,
  listagg(item || '(' || item_count || ')', '/') within group (order by item) as items
from (
  select id, name, item, count(*) as item_count
  from (
    select id, name, regexp_substr(items, '(.*?)(/|$)', 1, level, null, 1) as item
    from your_table
    connect by level < regexp_count(items, '(.*?)(/|$)')
    and prior id = id
    and prior dbms_random.value is not null
  )
  group by id, name, item
)
group by id, name
order by id;

以您的示例和另一个通过CTE提供的顺序不同的示例:

with your_table (id, name, items) as (
            select 1, 'JFK', '100/100/100/200/300/300' from dual
  union all select 2, 'LBJ', '100/300/100/200/100' from dual
)
select ...

该查询得到

        ID NAM ITEMS                                             
---------- --- --------------------------------------------------
         1 JFK 100(3)/200(1)/300(2)                              
         2 LBJ 100(3)/200(1)/300(1)