PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Substituindo o valor no campo vazio depois de usar split_part


split_part() retorna a string vazia ('' ) - não NULL - quando a parte a ser devolvida estiver vazia ou inexistente. É por isso que COALESCE não faz nada aqui. E a string vazia ('' ) não tem representação como integer value, portanto, ele gera um erro ao tentar convertê-lo.

O caminho mais curto neste exemplo deve ser GREATEST(split_part( ... ) , '0') antes da conversão, já que a string vazia é classificada antes de qualquer outra string não vazia ou até mesmo NULL (em qualquer localidade). Em seguida, use DISTINCT ON () para obter a linha com a "maior" versão para cada id .

Configuração do teste

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');

Soluções

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

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

Ou você poderia também use NULLIF e use NULLS LAST (em ordem decrescente) para classificar:
SELECT DISTINCT ON (id) *
FROM   tbl
ORDER  BY id, NULLIF(split_part(version, '-', 2), '')::int DESC NULLS LAST;

Mesmo resultado.

Ou um CASE mais explícito declaração:
CASE WHEN split_part(version, '-', 2) = '' THEN '0' ELSE split_part(version, '-', 2) END

dbfiddle aqui

Relacionado: