我在数据库中有这样的数据
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公式[ summ(all(min_hrv)) + summ(all(max_hrv)) ] / count(all(min_hrv)) + all(max_hrv))
获取AVG值,因为轴字符串结果将是((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
仍在strin中,结果是:
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)
也许有人知道这种问题更简单正确的方法吗?
答案 0 :(得分: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)
答案 1 :(得分:1)
您要查找的模式应该与#
之后的数字,一连串的数字和一个/
字符相同。使用regexp_matches
,仅当您将模式的 part 包装在一对圆括号中时,才可以提取该部分。
解决方案是
regexp_matches(your_col, '#\d+/(\d+)', 'g')
请注意,g
代表global
,这意味着将返回在字符串中找到的所有匹配项。
模式详细信息
\d+
-1个或更多(+
)位数字/
-一个/
字符(\d+)
-捕获第1组:1个或更多数字请参见regex demo。
如果在'(\d+)/(\d+)#(\d+)/(\d+)'
正则表达式的不同部分中使用一对括号,则可以从数据中提取特定位。要提取min_hr
,请使用'(\d+)/\d+#\d+/\d+'
。