split_part()
mengembalikan string kosong (''
) - bukan NULL
- ketika bagian yang akan dikembalikan kosong atau tidak ada. Itu sebabnya COALESCE
tidak melakukan apa-apa di sini. Dan string kosong (''
) tidak memiliki representasi sebagai integer
value, sehingga memunculkan kesalahan saat mencoba mentransmisikannya.
Cara terpendek dalam contoh ini adalah GREATEST(split_part( ... ) , '0')
sebelum casting, karena string kosong diurutkan sebelum string non-kosong lainnya atau bahkan NULL (di lokal mana pun). Kemudian gunakan DISTINCT ON ()
untuk mendapatkan baris dengan version
"terbesar" untuk setiap id
.
Pengaturan pengujian
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');
Solusi
SELECT DISTINCT ON (id) *
FROM tbl
ORDER BY id, GREATEST(split_part(version, '-', 2), '0')::int DESC;
Hasil:
id | version
----+---------
10 | 10-111
11 | 10-2
Atau kamu bisa juga gunakan NULLIF
dan gunakan NULLS LAST
(dalam urutan menurun) untuk mengurutkan:
SELECT DISTINCT ON (id) *
FROM tbl
ORDER BY id, NULLIF(split_part(version, '-', 2), '')::int DESC NULLS LAST;
Hasil yang sama.
Atau CASE
yang lebih eksplisit pernyataan:
CASE WHEN split_part(version, '-', 2) = '' THEN '0' ELSE split_part(version, '-', 2) END
dbfiddle di sini
Terkait:
- Urutkan string varchar sebagai numerik
- Pilih dulu baris di setiap grup GROUP BY?
- Urutkan PostgreSQL berdasarkan waktu asc, null dulu?
- Cara konversi kosong ke nol di PostgreSQL?