将子字符串转换为数字格式后如何使用AVG()函数?

时间:2017-03-18 08:57:45

标签: sql oracle average substr

在我的示例中有两列,如:" 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既不显示任何结果,也不显示错误。

有人可以就此问题提供帮助吗?

2 个答案:

答案 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的基本字符串函数存在问题。

在这里演示:

Rextester

答案 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;

Demo