Bygger på dine testdata, men dette fungerer med vilkårlige data. Dette fungerer med et vilkårligt antal elementer i strengen.
Registrer en sammensat type, der består af én text og et integer værdi én gang pr. database. Jeg kalder det ai :
CREATE TYPE ai AS (a text, i int);
Tricket er at danne et array af ai fra hver værdi i kolonnen.
regexp_matches() med mønsteret (\D*)(\d*) og g option returnerer én række for hver kombination af bogstaver og tal. Plus en irrelevant dinglende række med to tomme strenge '{"",""}' Filtrering eller undertrykkelse af det ville blot øge omkostningerne. Aggreger dette i en matrix efter at have erstattet tomme strenge ('' ) med 0 i integer komponent (som '' kan ikke castes til integer ).
NULL værdier sorteres først - eller du er nødt til at bruge dem i særlige tilfælde - eller brug hele shebang i en STRICT funktion som @Craig foreslår.
Postgres 9.4 eller nyere
SELECT data
FROM alnum
ORDER BY ARRAY(SELECT ROW(x[1], CASE x[2] WHEN '' THEN '0' ELSE x[2] END)::ai
FROM regexp_matches(data, '(\D*)(\d*)', 'g') x)
, data;
db<>spil her
Postgres 9.1 (oprindeligt svar)
Testet med PostgreSQL 9.1.5, hvor regexp_replace() havde en lidt anderledes adfærd.
SELECT data
FROM (
SELECT ctid, data, regexp_matches(data, '(\D*)(\d*)', 'g') AS x
FROM alnum
) x
GROUP BY ctid, data -- ctid as stand-in for a missing pk
ORDER BY regexp_replace (left(data, 1), '[0-9]', '0')
, array_agg(ROW(x[1], CASE x[2] WHEN '' THEN '0' ELSE x[2] END)::ai)
, data -- for special case of trailing 0
Tilføj regexp_replace (left(data, 1), '[1-9]', '0') som første ORDER BY element for at tage sig af førende cifre og tomme strenge.
Hvis specialtegn som {}()"', kan forekomme, bliver du nødt til at undslippe dem i overensstemmelse hermed.
@Craigs forslag om at bruge en ROW expression tager sig af det.
BTW, dette vil ikke køre i sqlfiddle, men det gør det i min db-klynge. JDBC er ikke op til det. sqlfiddle klager:
Metoden org.postgresql.jdbc3.Jdbc3Array.getArrayImpl(long,int,Map) er endnu ikke implementeret.
Dette er siden blevet rettet:https://sqlfiddle.com/#!17/fad6e/1