sql >> Base de Datos >  >> RDS >> PostgreSQL

Sustituyendo el valor en un campo vacío después de usar split_part

split_part() devuelve la cadena vacía ('' ) - no NULL - cuando la pieza a devolver esté vacía o no exista. Por eso COALESCE hace nada aquí. Y la cadena vacía ('' ) no tiene representación como integer valor, por lo tanto, arroja un error al intentar lanzarlo.

El camino más corto en este ejemplo debería ser GREATEST(split_part( ... ) , '0') antes de la conversión, ya que la cadena vacía se ordena antes que cualquier otra cadena no vacía o incluso NULL (en cualquier configuración regional). Luego use DISTINCT ON () para obtener la fila con la version "mayor" para cada id .

Configuración de prueba

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

Soluciones

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

O usted podría también use NULLIF y use NULLS LAST (en orden descendente) para ordenar:

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

Mismo resultado.

O un CASE más explícito declaración:

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

dbfiddle aquí

Relacionado: