split_part()
vrátí prázdný řetězec (''
) – nikoli NULL
- když je díl, který má být vrácen, prázdný nebo neexistuje. Proto COALESCE
nedělá nic tady. A prázdný řetězec (''
) nemá zastoupení jako integer
hodnotu, proto při pokusu o přetypování vyvolá chybu.
Nejkratší cesta v tomto příkladu by měla být GREATEST(split_part( ... ) , '0')
před přetypováním, protože prázdný řetězec řadí před jakýkoli jiný neprázdný řetězec nebo dokonce NULL (v jakémkoli národním prostředí). Poté použijte DISTINCT ON ()
získat řádek s "největší" version
pro každé id
.
Testovací nastavení
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');
Řešení
SELECT DISTINCT ON (id) *
FROM tbl
ORDER BY id, GREATEST(split_part(version, '-', 2), '0')::int DESC;
Výsledek:
id | version
----+---------
10 | 10-111
11 | 10-2
Nebo můžete použijte také NULLIF
a použijte NULLS LAST
(v sestupném pořadí) k řazení:
SELECT DISTINCT ON (id) *
FROM tbl
ORDER BY id, NULLIF(split_part(version, '-', 2), '')::int DESC NULLS LAST;
Stejný výsledek.
Nebo explicitnější CASE
prohlášení:
CASE WHEN split_part(version, '-', 2) = '' THEN '0' ELSE split_part(version, '-', 2) END
dbfiddle zde
Související:
- Objednejte řetězec varchar jako číselný
- Vyberte nejdříve řádek v každé skupině GROUP BY?
- Řazení PostgreSQL podle data a času asc, nejprve null?
- Jak na to převést prázdné na null v PostgreSQL?