split_part()
връща празния низ (''
) - не NULL
- когато частта за връщане е празна или несъществуваща. Ето защо COALESCEкод>
не прави нищо тук. И празният низ (''
) няма представяне като цяло число
стойност, следователно извежда грешка при опит за преобразуване.
Най-краткият път в този пример трябва да бъде GREATEST(split_part( ... ), '0')
преди кастинг, тъй като празният низ сортира преди всеки друг непразен низ или дори NULL (във всеки локал). След това използвайте DISTINCT ON ()
за да получите реда с "най-голямата" версия
за всеки id
.
Тестова настройка
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');
Решения
SELECT DISTINCT ON (id) *
FROM tbl
ORDER BY id, GREATEST(split_part(version, '-', 2), '0')::int DESC;
Резултат:
id | version
----+---------
10 | 10-111
11 | 10-2
Или вие можете също използвайте NULLIF
и използвайте NULLS LAST
(в низходящ ред), за да сортирате:
SELECT DISTINCT ON (id) *
FROM tbl
ORDER BY id, NULLIF(split_part(version, '-', 2), '')::int DESC NULLS LAST;
Същият резултат.
Или по-ясен CASE
изявление:
CASE WHEN split_part(version, '-', 2) = '' THEN '0' ELSE split_part(version, '-', 2) END
dbfiddle тук
Свързани:
- Поръчайте varchar низ като число
- Изберете първо ред във всяка група GROUP BY?
- PostgreSQL сортиране по дата и час възходящ, първо нула?
- Как да конвертирате празно в null в PostgreSQL?