Postgresql – 根据 varchar(转换为 float)double precision 异常排序

huangapple go评论120阅读模式
英文:

Postgresql - Order by varchar (cast to float) double precision exception

问题

我正在尝试按包含从null到'1'、'1.1'、'9.2'、'12'等值的varchar列对表行列表进行排序。在某些在线PostgreSQL数据库上,我的代码可以正常运行,但在此处遇到了双精度异常。

select *  
from api r 
  join santa_api v on v.id = r.api_id 
order by r.api_id, r.prefix_1::float
英文:

I am trying to sort a list of table rows based on varchar column that contains values from null to like '1', '1.1', '9.2','12', etc...

Getting the double precision exception, while on some online postgresql database my code works.

select *  
from api r 
  join santa_api v on v.id = r.api_id 
order by r.api_id, r.prefix_1::float

答案1

得分: 0

你可以尝试使用正则表达式,以便只在字符串仅包含数字、小数点和科学计数法时进行转换。即以下正则表达式匹配以可选的加号或减号开头,后跟零个或多个数字的字符串。然后可能有一个可选的小数点,后跟一个或多个数字。最后,可能包括一个可选的科学计数法,其中包含字母 'e' 或 'E',后面跟一个可选的加号或减号和一个或多个数字。

SELECT column_name
FROM table_name
ORDER BY
    CASE
        WHEN column_name ~ '^[+-]?\d*\.?\d+([eE][+-]?\d+)?$'
        THEN column_name::numeric
        ELSE NULL
    END;

你可以选择一些其他默认值,而不是NULL,这由你决定。这里是一个有效的示例:

SELECT column_name
FROM (VALUES ('10.7'), ('2.1'), ('3.5'), ('fred')) AS t(column_name)
ORDER BY
    CASE
        WHEN column_name ~ '^[+-]?\d*\.?\d+([eE][+-]?\d+)?$'
        THEN column_name::numeric
        ELSE NULL
    END;
column_name
2.1
3.5
10.7
fred

fiddle

英文:

You could try using regex so that it only attempts the conversion when the string contains only digits, decimal points and scientific notation. i.e. Th regex below matches a string that starts with an optional plus or minus sign followed by zero or more digits. Then there may be an optional decimal point followed by one or more digits. Finally, there may be optional scientific notation consisting of the letter ‘e’ or ‘E’ followed by an optional plus or minus sign and one or more digits.

SELECT column_name
FROM table_name
ORDER BY
    CASE
        WHEN column_name ~ '^[+-]?\d*\.?\d+([eE][+-]?\d+)?$'
        THEN column_name::numeric
        ELSE NULL
    END;

You could choose some other default value than NULL, that's up to you. here is a working example:

SELECT column_name
FROM (VALUES ('10.7'), ('2.1'), ('3.5'), ('fred')) AS t(column_name)
ORDER BY
    CASE
        WHEN column_name ~ '^[+-]?\d*\.?\d+([eE][+-]?\d+)?$'
        THEN column_name::numeric
        ELSE NULL
    END;
column_name
2.1
3.5
10.7
fred

fiddle

huangapple
  • 本文由 发表于 2023年3月8日 15:28:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/75670316.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定