split_part()
zwraca pusty ciąg (''
) - nie NULL
- gdy zwracana część jest pusta lub nie istnieje. Dlatego COALESCE
nie robi nic tutaj. Oraz pusty ciąg (''
) nie ma reprezentacji jako integer
wartość, dlatego zgłasza błąd podczas próby jej rzutowania.
Najkrótszą drogą w tym przykładzie powinna być GREATEST(split_part( ... ) , '0')
przed rzutowaniem, ponieważ pusty ciąg jest sortowany przed jakimkolwiek innym niepustym ciągiem lub nawet NULL (w dowolnym języku). Następnie użyj DISTINCT ON ()
aby uzyskać wiersz z "największą" wersją
dla każdego id
.
Konfiguracja testowa
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');
Rozwiązania
SELECT DISTINCT ON (id) *
FROM tbl
ORDER BY id, GREATEST(split_part(version, '-', 2), '0')::int DESC;
Wynik:
id | version
----+---------
10 | 10-111
11 | 10-2
Lub mogłeś użyj także NULLIF
i użyj NULLS LAST
(w porządku malejącym), aby posortować:
SELECT DISTINCT ON (id) *
FROM tbl
ORDER BY id, NULLIF(split_part(version, '-', 2), '')::int DESC NULLS LAST;
Ten sam wynik.
Lub bardziej wyraźny CASE
oświadczenie:
CASE WHEN split_part(version, '-', 2) = '' THEN '0' ELSE split_part(version, '-', 2) END
dbfiddle tutaj
Powiązane:
- Zamów ciąg varchar jako numeryczny
- Wybierz najpierw wiersz w każdej grupie GROUP BY?
- PostgreSQL Sortuj według daty i godziny asc, najpierw null?
- Jak przekonwertować pusty na null w PostgreSQL?