在我的示例中有两列,如:" ID" (NUMBER)和" NUMBER_COUNT" (VARCHAR2)目前看起来像:
ID: 1234567 -> NUMBER_COUNT = ':123:999:100:500:502:'
ID: 1111111 -> NUMBER_COUNT = ':444:543:100:664:404:'
我希望得到按ID分组的NUMBER_COUNT个AVG(),因此输出应如下所示:
ID numbers_avg
1234567 444.8
1111111 431
我已经尝试过了:
select
e.ID,
AVG(to_number(substr(e.NUMBER_COUNT, instr(e.NUMBER_COUNT, ':', 1, level) + 1,
instr(e.NUMBER_COUNT, ':', 1, level + 1) - instr(e.NUMBER_COUNT, ':', 1,
level) - 1),'99999999D99999')) as numbers_avg
from TABLE e
connect by level <= length(e.NUMBER_COUNT) - length(replace(e.NUMBER_COUNT, ':')) - 1
group by e.ID;
该声明可以执行。不幸的是,ORACLE既不显示任何结果,也不显示错误。
有人可以就此问题提供帮助吗?
答案 0 :(得分:0)
我感觉你在某种程度上试图在NUMBER_COUNT
列中爆炸冒号分隔的字符串,然后使用GROUP BY
汇总数字。我认为这里最简单的方法可能就是使用SUBSTR()
并取5个数字的平均值,根据需要投出每个数字。
SELECT ID, (CAST(SUBSTR(NUMBER_COUNT, 2, 3) AS NUMBER) +
CAST(SUBSTR(NUMBER_COUNT, 6, 3) AS NUMBER) +
CAST(SUBSTR(NUMBER_COUNT, 10, 3) AS NUMBER) +
CAST(SUBSTR(NUMBER_COUNT, 14, 3) AS NUMBER) +
CAST(SUBSTR(NUMBER_COUNT, 18, 3) AS NUMBER)) / 5 AS numbers_avg
FROM yourTable
请注意,我希望这种方法更快比使用其他人建议的REGEXP_SUBSTR()
更快。我在这里看不到正则表达式的必要性,因为Oracle的基本字符串函数存在问题。
在这里演示:
答案 1 :(得分:0)
首先,您不应该以这种方式存储数据。规范化结构将是最佳解决方案。
目前,您可以使用regexp_substr
并修复connect by
以使用sys_guid()
创建循环。
select
id,
avg(regexp_substr(number_count, '\d+', 1, level))
from your_table
connect by level <= regexp_count(number_count, ':')
and prior id = id
and prior sys_guid() is not null
group by id;