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

Remplacement de la valeur dans un champ vide après l'utilisation de split_part

split_part() renvoie la chaîne vide ('' ) - pas NULL - lorsque la pièce à restituer est vide ou inexistante. C'est pourquoi COALESCE ne fait rien ici. Et la chaîne vide ('' ) n'a pas de représentation en tant que integer valeur, par conséquent, il génère une erreur lors de la tentative de conversion.

Le chemin le plus court dans cet exemple devrait être GREATEST(split_part( ... ) , '0') avant le transtypage, car la chaîne vide est triée avant toute autre chaîne non vide ou même NULL (dans n'importe quelle locale). Ensuite, utilisez DISTINCT ON () pour obtenir la ligne avec la "plus grande" version pour chaque id .

Configuration du test

CREATE TABLE tbl (
   id      integer NOT NULL
 , version text    NOT NULL
);

INSERT INTO tbl VALUES
     (10, '10-2')
   , (10, '10-1')
   , (10, '10')      -- missing subversion
   , (10, '10-111')  -- multi-digit number
   , (11, '11-1')
   , (11, '11-0')    -- proper '0'
   , (11, '11-')     -- missing subversion but trailing '-'
   , (11, '11-2');

Solutions

SELECT DISTINCT ON (id) *
FROM   tbl
ORDER  BY id, GREATEST(split_part(version, '-', 2), '0')::int DESC;

Résultat :

 id | version 
----+---------
 10 | 10-111
 11 | 10-2

Ou tu pourrais utilisez également NULLIF et utilisez NULLS LAST (par ordre décroissant) pour trier :

SELECT DISTINCT ON (id) *
FROM   tbl
ORDER  BY id, NULLIF(split_part(version, '-', 2), '')::int DESC NULLS LAST;

Même résultat.

Ou un CASE plus explicite déclaration :

CASE WHEN split_part(version, '-', 2) = '' THEN '0' ELSE split_part(version, '-', 2) END

dbfiddle ici

Connexe :