我想要的是通过这种方式来计算字符串的出现次数:
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,但是如果您能提供通用的产品,可能会帮助更多的人。
谢谢:)
答案 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)