【问题标题】:Typecast string to integer将字符串类型转换为整数
【发布时间】:2012-05-09 14:34:34
【问题描述】:

我正在从在 Varchar 中具有原始提要的表中导入数据,我需要将 varchar 中的列导入到字符串列中。我尝试使用<column_name>::integerto_number(<column_name>,'9999999'),但出现错误,因为有一些空字段,我需要将它们作为空或空值检索到新表中。

【问题讨论】:

  • 你能告诉我们错误信息吗?这会有所帮助
  • 如果错误类似于Query failed: ERROR: invalid input syntax for integer: "",请使用intval() 函数查看解决方案

标签: postgresql


【解决方案1】:

大胆猜测:如果你的值是一个空字符串,你可以使用 NULLIF 将其替换为 NULL:

SELECT
    NULLIF(your_value, '')::int

【讨论】:

    【解决方案2】:

    您甚至可以进一步限制这个合并的字段,例如:-

    SELECT CAST(coalesce(<column>, '0') AS integer) as new_field
    from <table>
    where CAST(coalesce(<column>, '0') AS integer) >= 10; 
    

    【讨论】:

    • 为什么合并需要强制转换?
    【解决方案3】:

    如果您需要将空列视为NULLs,请尝试以下操作:

    SELECT CAST(nullif(<column>, '') AS integer);
    

    另一方面,如果您确实需要避免使用 NULL 值,请尝试:

    SELECT CAST(coalesce(<column>, '0') AS integer);
    

    我同意,错误信息会有很大帮助。

    【讨论】:

      【解决方案4】:

      我成功避免因 NULL、特殊字符或空字符串而出错的唯一方法是这样做:

      SELECT REGEXP_REPLACE(COALESCE(<column>::character varying, '0'), '[^0-9]*' ,'0')::integer FROM table
      

      【讨论】:

      • 对我来说(9.6.2)这是唯一有效的方法,所有其他答案都失败了。
      • 您不能添加WHERE &lt;column&gt; != NULL吗?
      【解决方案5】:

      我无法对 Lukas 的帖子发表评论(声誉太低?我是新手)。

      在我的 PG 设置中 to_number(NULL) 不起作用,所以我的解决方案是:

      SELECT CASE WHEN column = NULL THEN NULL ELSE column :: Integer END
      FROM table
      

      【讨论】:

      • 这应该可行,但它应该与不那么冗长的NULLIF() 方法完全等效。该标准实际上将 NULLIF 定义为 CASE 谓词的一种形式。
      【解决方案6】:

      如果值包含非数字字符,您可以将值转换为整数,如下所示:

      SELECT CASE WHEN <column>~E'^\\d+$' THEN CAST (<column> AS INTEGER) ELSE 0 END FROM table;
      

      CASE运算符检查,如果匹配到整数模式,则将速率转换为整数,否则返回0

      【讨论】:

        【解决方案7】:

        常见问题

        像这样天真地将任何字符串转换为整数

        SELECT ''::integer
        

        经常导致著名的错误:

        Query failed: ERROR: invalid input syntax for integer: ""
        

        问题

        PostgreSQL 没有为 safely 类型将任何字符串转换为整数的预定义函数。

        解决方案

        创建一个受 PHP 的 intval() 函数启发的用户定义函数。

        CREATE FUNCTION intval(character varying) RETURNS integer AS $$
        
        SELECT
        CASE
            WHEN length(btrim(regexp_replace($1, '[^0-9]', '','g')))>0 THEN btrim(regexp_replace($1, '[^0-9]', '','g'))::integer
            ELSE 0
        END AS intval;
        
        $$
        LANGUAGE SQL
        IMMUTABLE
        RETURNS NULL ON NULL INPUT;
        

        用法

        /* Example 1 */
        SELECT intval('9000');
        -- output: 9000
        
        /* Example 2 */
        SELECT intval('9gag');
        -- output: 9
        
        /* Example 3 */
        SELECT intval('the quick brown fox jumps over the lazy dog');
        -- output: 0
        

        【讨论】:

        • 对于非常大的数字会失败。如果你也捕获异常,它会完美地工作
        • @jaisonDavis 该主题是关于整数的,这就是为什么预计该解决方案对于非常大的数字会失败的原因。您可能需要考虑创建与此解决方案类似的函数,例如:bigintval(),并为该函数替换任何显示integer 的内容并将其替换为bigint。失败可能只是 data type 限制。
        【解决方案8】:

        你可以使用这个查询

        SUM(NULLIF(conversion_units, '')::numeric)
        

        【讨论】:

          【解决方案9】:

          如果你的列有小数点

          select NULLIF('105.0', '')::decimal
          

          【讨论】:

            【解决方案10】:

            这对我有用:

            select (left(regexp_replace(coalesce('<column_name>', '0') || '', '[^0-9]', '', 'g'), 8) || '0')::integer
            

            为了方便查看:

            select (
                left(
                    regexp_replace(
                        -- if null then '0', and convert to string for regexp
                        coalesce('<column_name>', '0') || '',
                        '[^0-9]',
                        '',
                        'g'
                    ),      -- remove everything except numbers
                    8       -- ensure ::integer doesn't overload
                ) || '0'    -- ensure not empty string gets to ::integer
            )::integer
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2011-05-15
              • 1970-01-01
              • 1970-01-01
              • 2020-06-04
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多