Convert value from string representation in base N to numeric

拟墨画扇 提交于 2019-12-01 08:23:46

问题


On my database i keep a numbers in specific notation as varchar values. Is there any way to typecast this values into decimals with selected notation?

What i basically looking here should look like this:

SELECT to_integer_with_notation('d', '20')

 int4
 ---------
 13

One more example:

SELECT to_integer_with_notation('d3', '23')

 int4
 ---------
 302

回答1:


Unfortunately, there is no built-in function for that in PostgreSQL, but can be written fairly easy:

CREATE OR REPLACE FUNCTION number_from_base(num TEXT, base INTEGER)
  RETURNS NUMERIC
  LANGUAGE sql
  IMMUTABLE
  STRICT
AS $function$
SELECT sum(exp * cn)
FROM (
  SELECT base::NUMERIC ^ (row_number() OVER () - 1) exp,
         CASE
           WHEN ch BETWEEN '0' AND '9' THEN ascii(ch) - ascii('0')
           WHEN ch BETWEEN 'a' AND 'z' THEN 10 + ascii(ch) - ascii('a')
         END cn
  FROM regexp_split_to_table(reverse(lower(num)), '') ch(ch)
) sub
$function$;

Note: I used numeric as a return type, as int4 is not enough in many cases (with longer string input).

Edit: Here is a sample reverse function, which can convert a bigint to its text representation within a custom base:

CREATE OR REPLACE FUNCTION number_to_base(num BIGINT, base INTEGER)
  RETURNS TEXT
  LANGUAGE sql
  IMMUTABLE
  STRICT
AS $function$
WITH RECURSIVE n(i, n, r) AS (
    SELECT -1, num, 0
  UNION ALL
    SELECT i + 1, n / base, (n % base)::INT
    FROM n
    WHERE n > 0
)
SELECT string_agg(ch, '')
FROM (
  SELECT CASE
           WHEN r BETWEEN 0 AND 9 THEN r::TEXT
           WHEN r BETWEEN 10 AND 35 THEN chr(ascii('a') + r - 10)
           ELSE '%'
         END ch
  FROM n
  WHERE i >= 0
  ORDER BY i DESC
) ch
$function$;

Example usage:

SELECT number_to_base(1248, 36);

-- +----------------+
-- | number_to_base |
-- +----------------+
-- | yo             |
-- +----------------+


来源:https://stackoverflow.com/questions/24425022/convert-value-from-string-representation-in-base-n-to-numeric

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!