我在数据库中有这样的数据
61/10#61/12,0/12,10/16,0/21,0/12#61/33,0/28#0/34,0/23#0/28
像10/16
(没有#
)这样的部分是无效的,不应该用于计算,
但所有其他都有下一个格式 min_hr + "/"+ min_hrv + "#"+ max_hr + "/"+ max_hrv
问题是通过下一个 psevdo 公式获取 AVG 值 [ summ(all(min_hrv)) + summ(all(max_hrv)) ]/count(all(min_hrv)) + all(max_hrv))
,对于 axample 字符串结果将是 ((10 + 12 + 28 + 23) + (12 + 33 + 34 + 28))/8)
== 22
我尝试的是:
SELECT regexp_replace(
'61/10#61/12,0/12,10/16,0/21,0/12#61/33,0/28#0/34,0/23#0/28',
',\d+/\d+,', ',',
'g'
);
删除无效数据但 10/16
仍在字符串中,结果是:
regexp_replace
--------------------------------------------------
61/10#61/12,10/16,0/12#61/33,0/28#0/34,0/23#0/28
如果很好地清理字符串,我的计划将以这种方式拆分为数组,对于 max(不是完整的解决方案,有空字符串),对于 min 没有解决方案:
SELECT
regexp_split_to_array(
regexp_replace(
'61/10#61/12,0/12,0/12#61/33,0/28#0/34,0/23#0/28',
',\d+/\d+,', ',',
'g'
)
,',?\d+/\d+#\d+/'
);
结果是:
regexp_split_to_array
-----------------------
{"",12,33,34,28}
然后计算数据,像这样:
SELECT ((
SELECT sum(tmin.unnest)
FROM
(SELECT unnest('{10,12,28,23}'::int[])) as tmin
)
+
(
SELECT sum(tmax.unnest)
FROM
(SELECT unnest('{12,33,34,28}'::int[])) as tmax
))
/
(SELECT array_length('{12,33,34,28}'::int[], 1) * 2)
可能有人知道解决此类问题的更简单正确的方法吗?
最佳答案
使用regexp_matches()
:
select (regexp_matches(
'61/10#61/12,0/12,0/12#61/33,0/28#0/34,0/23#0/28',
'\d+#\d+/(\d+)',
'g'))[1]
regexp_matches
----------------
12
33
34
28
(4 rows)
整个计算可能是这样的:
with my_data(str) as (
values
('61/10#61/12,0/12,10/16,0/21,0/12#61/33,0/28#0/34,0/23#0/28')
),
min_max as (
select
(regexp_matches(str, '(\d+)#\d+', 'g'))[1] as min_hrv,
(regexp_matches(str, '\d+#\d+/(\d+)', 'g'))[1] as max_hrv
from my_data
)
select avg(min_hrv::int+ max_hrv::int) / 2 as result
from min_max;
result
---------------------
22.5000000000000000
(1 row)
关于regex - 从字符串中获取整数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54762061/