Clasificación de números natural o humanizada de cadenas de palabras y números mixtas

Siguiendo aesta pregunta porSivaram ChintalapudiEstoy interesado en saber si es práctico hacerlo en PostgreSQL.Clasificación natural o "humanizada" "de cadenas que contienen una mezcla de números de varios dígitos y palabras / letras. No hay un patrón fijo de palabras y números en las cadenas, y puede haber más de un número de varios dígitos en una cadena.

El único lugar donde he visto esto hecho de manera rutinaria es en el Finder de Mac OS, que ordena los nombres de archivos que contienen números y palabras mixtas de forma natural, colocando "20" después de "3", no antes.

El orden de intercalación deseado se produciría mediante un algoritmo que dividirá cada cadena en bloques en los límites de los números de letras, luego ordenará cada parte, tratando los bloques de letras con intercalación normal y los bloques de números como números enteros para propósitos de intercalación. Asi que:

'AAA2fred' se convertiría('AAA',2,'fred') y'AAA10bob' se convertiría('AAA',10,'bob'). Estos se pueden clasificar como se desee:

regress=# WITH dat AS ( VALUES ('AAA',2,'fred'), ('AAA',10,'bob') )
regress-# SELECT dat FROM dat ORDER BY dat;
     dat      
--------------
 (AAA,2,fred)
 (AAA,10,bob)
(2 rows)

en comparación con el orden de colación de cadenas habitual:

regress=# WITH dat AS ( VALUES ('AAA2fred'), ('AAA10bob') )
regress-# SELECT dat FROM dat ORDER BY dat;
    dat     
------------
 (AAA10bob)
 (AAA2fred)
(2 rows)

Sin embargo, el método de comparación de registros no se generaliza porque Pg no comparará las construcciones ROW (..) o los registros de números desiguales de entradas.

Dados los datos de muestraen este SQLFiddle la intercalación predeterminada en_AU.UTF-8 produce el ordenamiento:

1A, 10A, 2A, AAA10B, AAA11B, AAA1BB, AAA20B, AAA21B, X10C10, X10C2, X1C1, X1C10, X1C3, X1C30, X1C4, X2C1

pero yo quiero:

1A, 2A, 10A, AAA1BB, AAA10B, AAA11B, AAA20B, AAA21B, X1C1, X1C3, X1C4, X1C10, X1C30, X2C1, X10C10, X10C2

Estoy trabajando con PostgreSQL 9.1 en este momento, pero las sugerencias de 9.2 solo estarán bien. Me interesa recibir consejos sobre cómo lograr un método eficiente de división de cadenas y cómo comparar los datos divididos resultantes en la intercalación de cadenas y números que se describe. O, por supuesto, en enfoques completamente diferentes y mejores que no requieren la división de cadenas.

PostgreSQL no parece admitir funciones de comparación, de lo contrario, esto podría hacerse con bastante facilidad con un comparador recursivo y algo así comoORDER USING comparator_fn y uncomparator(text,text) función. Por desgracia, esa sintaxis es imaginaria.

Actualizar: Publicación de blog sobre el tema..

Respuestas a la pregunta(6)

Su respuesta a la pregunta