PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Sostituendo il valore in un campo vuoto dopo aver usato split_part

split_part() restituisce la stringa vuota ('' ) - non NULL - quando il pezzo da restituire è vuoto o inesistente. Ecco perché COALESCE non fa nulla qui. E la stringa vuota ('' ) non ha alcuna rappresentazione come integer value, quindi genera un errore quando si tenta di eseguirne il cast.

La via più breve in questo esempio dovrebbe essere GREATEST(split_part( ... ) , '0') prima del casting, poiché la stringa vuota viene ordinata prima di qualsiasi altra stringa non vuota o anche NULL (in qualsiasi locale). Quindi usa DISTINCT ON () per ottenere la riga con la version "più grande". per ogni id .

Impostazione di prova

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

Soluzioni

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

Risultato:

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

Oppure tu potresti usa anche NULLIF e usa NULLS LAST (in ordine decrescente) per ordinare:

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

Stesso risultato.

Oppure un CASE più esplicito dichiarazione:

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

dbfiddle qui

Correlati: