如何用SQL从字符串中提取数值计算百分比?
问题
我有一个存储进度状态的progress列,数据示例如下:
| progress |
|---|
| 10 of 100 completed |
| 20 of 100 completed |
| 40 of 200 completed |
| 69 of 420 completed |
...
我想了解是否可以通过一行SQL语句直接计算每行的百分比?还是必须先用正则表达式将数值拆分到两列后再进行计算?我尝试构思了一个思路(抱歉写法不规范,我不太会写SQL):
regexep (r'^[0-9]+) / regexp (r'[0-9]$)
解决方案
当然可以用一行SQL直接算出百分比,完全不用先把数值拆分到单独列里。关键就是用正则把已完成的数字和总数字提出来,直接做除法运算就行。不同数据库的正则函数写法不一样,给你几个常用数据库的实现:
MySQL/MariaDB
SELECT progress, -- 提取开头的已完成数字 CAST(REGEXP_SUBSTR(progress, '^[0-9]+') AS UNSIGNED) / -- 提取"completed"前面的总数字 CAST(REGEXP_SUBSTR(progress, '[0-9]+(?= completed)') AS UNSIGNED) * 100 AS completion_percent FROM your_table;
PostgreSQL
SELECT progress, -- 提取"of"前面的已完成数 (regexp_match(progress, '^([0-9]+) of'))[1]::numeric / -- 提取"of"和"completed"之间的总数 (regexp_match(progress, 'of ([0-9]+) completed'))[1]::numeric * 100 AS completion_percent FROM your_table;
SQL Server
SQL Server没有原生的正则提取函数,不过可以用字符串截取来实现:
SELECT progress, -- 提取第一个空格前的已完成数 CAST(SUBSTRING(progress, 1, CHARINDEX(' ', progress) - 1) AS INT) / -- 提取"of "之后、" completed"之前的总数 CAST(SUBSTRING(progress, CHARINDEX('of ', progress) + 3, CHARINDEX(' completed', progress) - CHARINDEX('of ', progress) - 3) AS FLOAT) * 100 AS completion_percent FROM your_table;
补充说明
- 上面的语句都会返回百分比数值,比如
10 of 100 completed会算出10.0 - 如果需要控制小数位数,用
ROUND()包一下计算式就行,比如ROUND(计算式, 2)就是保留两位小数 - 注意如果数据格式不规范(比如不是
X of Y completed的格式),可能会报错,建议先确认数据的一致性
内容的提问来源于stack exchange,提问作者acme64
相关产品推荐
相关产品推荐

