sql >> データベース >  >> RDS >> PostgreSQL

値をベースNの文字列表現から数値に変換します

    残念ながら、PostgreSQLにはそのための組み込み関数はありませんが、かなり簡単に記述できます:

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

    numericを使用しました リターンタイプとして、int4として 多くの場合(文字列入力が長い場合)では不十分です。

    編集bigintを変換できるリバース関数の例を次に示します。 カスタムベース内のテキスト表現へ:

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

    使用例:

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



    1. Sql selectgroupbyおよびstringconcat

    2. mysqlのn行目以降のすべてのレコードを削除するにはどうすればよいですか?

    3. Oracleから次のn個のロック解除された行を取得するにはどうすればよいですか?

    4. RailsPostgreSQL数値フィールドオーバーフローエラー