split_part()
geeft de lege string terug (''
) - niet NULL
- wanneer het te retourneren onderdeel leeg is of niet bestaat. Daarom COALESCE
doet niets hier. En de lege string (''
) heeft geen voorstelling als integer
waarde, vandaar dat het een foutmelding geeft wanneer het probeert te casten.
De kortste weg in dit voorbeeld is GREATEST(split_part( ... ) , '0')
vóór het casten, omdat de lege tekenreeks vóór elke andere niet-lege tekenreeks of zelfs NULL (in elke landinstelling) wordt gesorteerd. Gebruik dan DISTINCT ON ()
om de rij te krijgen met de "grootste" version
voor elke id
.
Testopstelling
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');
Oplossingen
SELECT DISTINCT ON (id) *
FROM tbl
ORDER BY id, GREATEST(split_part(version, '-', 2), '0')::int DESC;
Resultaat:
id | version
----+---------
10 | 10-111
11 | 10-2
Of je zou gebruik ook NULLIF
en gebruik NULLS LAST
(in aflopende volgorde) om te sorteren:
SELECT DISTINCT ON (id) *
FROM tbl
ORDER BY id, NULLIF(split_part(version, '-', 2), '')::int DESC NULLS LAST;
Zelfde resultaat.
Of een meer expliciete CASE
verklaring:
CASE WHEN split_part(version, '-', 2) = '' THEN '0' ELSE split_part(version, '-', 2) END
dbfiddle hier
Gerelateerd:
- Bestel varchar-tekenreeks als numeriek
- Selecteer eerst rij in elke GROUP BY-groep?
- PostgreSQL sorteren op datetime asc, eerst null?
- Hoe leeg naar null converteren in PostgreSQL?