如何从价格列中删除货币符号?

Posted

技术标签:

【中文标题】如何从价格列中删除货币符号?【英文标题】:How to remove currency symbol from price column? 【发布时间】:2015-02-17 06:39:16 【问题描述】:

我有一个价格列,它是字符串,包含来自世界各地的产品的价格,现在当我尝试执行 sum 之类的任何操作时,我遇到了错误。 所以我的问题是如何从所有国家/地区的价格列中删除货币符号?

这是我的示例输入:-

locale   price 
cs_CZ   2462475,38 K
da_DK   kr 591.872,50
de_AT    267,70
de_CH   CHF 1'998.99
de_DE   1.798,09 
en_AE   AED7,236.20
en_AU   $1,699.00 
en_BD   Tk999,999.00
en_HK   HK$6,188.00
en_HU   Ft344,524,655.48
tr_TR   2.344.697,66 TL

【问题讨论】:

不要存储这些字符!使用约束、正确的数据类型、触发器等,在插入/更新时清理数据! (现在你也有问题小数点或小数点...) 历史数据已经存在于表中,所以我无法清理。 是否允许更新表数据?如果它少于数百万行,您可以简单地一遍又一遍地使用 REPLACE 直到所有不同的货币符号和空格都消失,那么您就有小数点/逗号问题。如果它总是两位小数,这很容易,否则你可以看看最后的第三个字符,看看它是否是数字等等。 【参考方案1】:

Postgres 将大部分语言环境处理卸载到操作系统。所以 Postgres 货币转换例程只有在操作系统理解语言环境名称并且您的价格字符串与其预期格式匹配时才对您有效。

例如,Windows 不会接受 da_DK 作为语言环境,即使接受了,它也不会接受字符串 kr 591.872,50,因为它希望丹麦货币符号是 kr. 而不是 @987654324 @。

也就是说,我认为这应该在基于 Linux 的服务器上运行良好:

CREATE FUNCTION convert_currency(amount TEXT, locale TEXT) RETURNS NUMERIC AS
$$
BEGIN
  PERFORM set_config('lc_monetary', locale || '.UTF-8', True);
  RETURN amount::MONEY::NUMERIC;
END
$$
LANGUAGE plpgsql
SET lc_monetary TO DEFAULT;

【讨论】:

【参考方案2】:

您似乎有小数点和小数点逗号,但总是有两个小数(希望在其余数据中也是如此)。

    您可以首先将这些值放入值列表中进行测试(在需要时添加额外的单引号)。 然后你必须用正则表达式去掉空格和字母。在内部 SELECT 中,您将获得带有单引号和逗号的子字符串,用于千位分隔符。

    在外部 SELECT 中,您替换小数侧的小数逗号并去除整数侧的千位分隔符。结果被转换为数字类型,您可以用它来计算总和等。

    SELECT (
        regexp_replace(left(substring, length(substring) -3),'[.,'']','','g')
            || replace(right(substring, 3),',','.'))::numeric,
        *
        FROM (
            SELECT substring(column1 from '(([0-9]+[,.''])*[0-9]+[.,][0-9]2)[^0-9]*$'),
            column1
            FROM (
                VALUES ('2462475,38 K'),
                    ('kr 591.872,50'),
                    ('267,70'),
                    ('CHF 1''998.99'),
                    ('1.798,09'),
                    ('AED7,236.20'),
                    ('$1,699.00'),
                    ('Tk999,999.00'),
                    ('HK$6,188.00'),
                    ('Ft344,524,655.48'),
                    ('2.344.697,66 TL')
            ) currencies
        ) sq1;
    

以下是与 PostgreSQL 9.0 版本兼容的完整答案(未使用 left() 或 right() 函数)。值列表也被替换为 SELECT 查询,您可以将其替换为您自己的表和列。最后,所有内容都包含在一个 SELECT 查询中,该查询演示了 sum 函数的使用。

SELECT sum(numeric) FROM (
    SELECT (
        regexp_replace(substr(substring, 0, length(substring) -3),'[.,'']','','g')
            || replace(substr(substring, length(substring) -3, length(substring)),',','.'))::numeric,
        *
        FROM (
            SELECT substring(column1 from '(([0-9]+[,.''])*[0-9]+[.,][0-9]2)[^0-9]*$'),
                column1
                FROM (
                    SELECT column1 FROM your_table
                ) currencies
        ) sq1
    ) sq2

【讨论】:

我尝试运行上面的查询,但它抛出错误。 错误是什么?如果 PostgreSQL 版本太旧而无法识别左右函数,您可以例如将 left()-function 替换为:substr(substring, 0, length(substring) -3) 并将 right()-function 替换为:substr(substring, length(substring) -3, length(substring)) 如果是其他问题,请描述错误消息。

以上是关于如何从价格列中删除货币符号?的主要内容,如果未能解决你的问题,请参考以下文章

从字符串中提取货币和价格值

将 in_array 与货币符号一起使用?

如何从 coinmarketcap 获取谷歌表格上加密货币的当前价格?

从公开分类中的产品价格中删除美元符号

来自 NumberFormatter 的本地化货币符号

货币符号的 Web 服务