sql >> Database teknologi >  >> RDS >> PostgreSQL

Konverter værdi fra strengrepræsentation i basis N til numerisk

Desværre er der ingen indbygget funktion til det i PostgreSQL, men kan skrives ret nemt:

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$;
 

Bemærk :Jeg brugte numeric som en returtype, som int4 er ikke nok i mange tilfælde (med længere strenginput).

Rediger :Her er et eksempel på en omvendt funktion, som kan konvertere en bigint til dens tekstrepræsentation inden for en tilpasset 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$;
 

Eksempel på brug:

SELECT number_to_base(1248, 36); -- +----------------+ -- | number_to_base | -- +----------------+ -- | yo | -- +----------------+


  1. SQL - optælling af rækker med specifik værdi

  2. Har du brug for at kende klasse af en byte-array gemt i MySQL-databasen

  3. Hvad sker der egentlig med den søgen?

  4. PHP-forespørgsel giver ingen resultater