split_part()
gibt den leeren String zurück (''
) - nicht NULL
- wenn das zurückzusendende Teil leer oder nicht vorhanden ist. Deshalb COALESCE
macht nichts hier. Und der leere String (''
) hat keine Darstellung als integer
Wert, daher wird ein Fehler ausgegeben, wenn versucht wird, ihn umzuwandeln.
Der kürzeste Weg in diesem Beispiel sollte GREATEST(split_part( ... ) , '0')
DISTINCT ON ()
um die Zeile mit der "größten" version
zu erhalten für jede id
.
Testaufbau
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ösungen
SELECT DISTINCT ON (id) *
FROM tbl
ORDER BY id, GREATEST(split_part(version, '-', 2), '0')::int DESC;
Ergebnis:
id | version
----+---------
10 | 10-111
11 | 10-2
Oder Sie könnten Verwenden Sie auch NULLIF
und verwenden Sie NULLS LAST
(in absteigender Reihenfolge) zu sortieren:
SELECT DISTINCT ON (id) *
FROM tbl
ORDER BY id, NULLIF(split_part(version, '-', 2), '')::int DESC NULLS LAST;
Gleiches Ergebnis.
Oder ein expliziterer CASE
Aussage:
CASE WHEN split_part(version, '-', 2) = '' THEN '0' ELSE split_part(version, '-', 2) END
dbfiddle hier
Verwandte:
- Order varchar string as numeric
- Zuerst auswählen Zeile in jeder GROUP BY-Gruppe?
- PostgreSQL sortiert nach datetime asc, null zuerst?
- Anleitung In PostgreSQL leer in null umwandeln?