split_part()
returnerer den tomme streng (''
) - ikke NULL
- når den del, der skal returneres, er tom eller ikke-eksisterende. Det er derfor COALESCE
gør ingenting her. Og den tomme streng (''
) har ingen repræsentation som heltal
værdi, derfor giver den en fejl, når den forsøger at caste den.
Den korteste vej i dette eksempel bør være STORT(split_del( ... ), '0')
før casting, da den tomme streng sorterer før enhver anden ikke-tom streng eller endda NULL (i enhver lokalitet). Brug derefter DISTINCT ON ()
for at få rækken med den "største" version
for hvert id
.
Test opsætning
OPRET TABEL tbl ( id heltal IKKE NULL , versionstekst IKKE NULL); INSERT INTO tbl VALUES (10, '10-2') , (10, '10-1') , (10, '10 ') -- manglende subversion , (10, '10-111') -- flercifret tal , (11, '11-1') , (11, '11-0') -- korrekt '0' , ( 11, '11-') -- manglende undergravning, men efterfølgende '-' , (11, '11-2');
Løsninger
SELECT DISTINCT ON (id) *FROM tblORDER BY id, GREATEST(split_part(version, '-', 2), '0')::int DESC;
Resultat:
id | version ----+--------- 10 | 10-111 11 | 10-2
Eller du kunne brug også NULLIF
og brug NULLS LAST
(i faldende rækkefølge) for at sortere:
SELECT DISTINCT ON (id) *FROM tblORDER BY id, NULLIF(split_part(version, '-', 2), '')::int DESC NULLS LAST;
Samme resultat.
Eller en mere eksplicit CASE
erklæring:
CASE WHEN split_part(version, '-', 2) ='' THEN '0' ELSE split_part(version, '-', 2) END
dbfiddle her
Relateret:
- Bestil varchar-streng som numerisk
- Vælg først række i hver GRUPPE FOR gruppe?
- PostgreSQL sorter efter datetime asc, null først?
- Sådan gør du konvertere tom til null i PostgreSQL?