sql >> Databasteknik >  >> RDS >> PostgreSQL

Ersätter värde i tomt fält efter användning av split_part

split_part() returnerar den tomma strängen ('' ) - inte NULL - när delen som ska returneras är tom eller obefintlig. Det är därför COALESCE gör inget här. Och den tomma strängen ('' ) har ingen representation som heltal värde, därför ger det ett fel när det försöker casta det.

Den kortaste vägen i det här exemplet bör vara GREATEST(split_part( ... ), '0') före casting, eftersom den tomma strängen sorterar före någon annan icke-tom sträng eller till och med NULL (i valfri lokalitet). Använd sedan DISTINCT ON () för att få raden med den "största" versionen för varje id .

Testa installationen

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

Lösningar

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

Resultat:

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

Eller du kunde använd även NULLIF och använd NULL LAST (i fallande ordning) för att sortera:

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

Samma resultat.

Eller ett mer explicit CASE uttalande:

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

dbfiddle här

Relaterat:



  1. Stöder Postgres kapslade eller autonoma transaktioner?

  2. Hur skapar man en databas med doctrine2?

  3. MYSQL Välj på två värden en kolumn

  4. Optimera MySQL-frågor med IN-operator