将子字符串转换为数字格式后如何使用 AVG() 函数?
How to use AVG() function after converting a substring to a numeric format?
在我的示例中,有两列:"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 既不显示任何结果,也不显示错误。
有人可以就此问题提供帮助吗?
我觉得您在某种程度上试图分解 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 的基本字符串函数已经解决了这个问题。
此处演示:
首先,您不应该以这种方式存储数据。规范化结构将是最好的解决方案。
目前,您可以使用 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
在我的示例中,有两列:"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 既不显示任何结果,也不显示错误。
有人可以就此问题提供帮助吗?
我觉得您在某种程度上试图分解 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 的基本字符串函数已经解决了这个问题。
此处演示:
首先,您不应该以这种方式存储数据。规范化结构将是最好的解决方案。
目前,您可以使用 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;