PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Fractionner une chaîne avec deux délimiteurs et convertir le type

Si vous avez besoin de l'étape intermédiaire :

SELECT unnest(string_to_array(a, ' '))::float8
       -- or do something else with the derived table
FROM   unnest(string_to_array('3.584731 60.739211,3.590472 60.738030', ',')) a;

C'est plus verbeux que regexp_split_to_table() , mais peut toujours être plus rapide car les expressions régulières sont généralement plus coûteuses. (Tester avec EXPLAIN ANALYZE .)

J'ai d'abord divisé à ',' , et ensuite à ' ' - la séquence inversée de ce que vous décrivez semble plus adéquate.

Si besoin est, vous pouvez encapsuler ceci dans une fonction PL/pgSQL :

CREATE OR REPLACE FUNCTION public.split_string(_str text
                                             , _delim1 text = ','
                                             , _delim2 text = ' ')
  RETURNS SETOF float8 AS
$func$
BEGIN
   RETURN QUERY
   SELECT unnest(string_to_array(a, _delim2))::float8
          -- or do something else with the derived table from step 1
   FROM   unnest(string_to_array(_str, _delim1)) a;
END
$func$ LANGUAGE plpgsql IMMUTABLE;

Ou juste une fonction SQL :

CREATE OR REPLACE FUNCTION public.split_string(_str text
                                             , _delim1 text = ','
                                             , _delim2 text = ' ')
  RETURNS SETOF float8 AS
$func$
   SELECT unnest(string_to_array(a, _delim2))::float8
   FROM   unnest(string_to_array(_str, _delim1)) a
$func$ LANGUAGE sql IMMUTABLE;

Rendez-le IMMUTABLE pour permettre l'optimisation des performances et d'autres utilisations.

Appel (en utilisant les valeurs par défaut fournies pour _delim1 et _delim2 ):

SELECT * FROM split_string('3.584731 60.739211,3.590472 60.738030');

Ou :

SELECT * FROM split_string('3.584731 60.739211,3.590472 60.738030', ',', ' ');

Le plus rapide

Pour des performances optimales, combinez translate() avec unnest(string_to_array(...)) :

SELECT unnest(
          string_to_array(
             translate('3.584731 60.739211,3.590472 60.738030', ' ', ',')
           , ','
          )
       )::float8