Гуманизированная или натуральная числовая сортировка смешанных строк из слова и номера

Продолжаяэтот вопрос поСиварам Чинталапуди, Меня интересует, практично ли это делать в PostgreSQLестественная или «гуманизированная» сортировка "строк, которые содержат смесь многозначных чисел и слов / букв. В строках нет фиксированного набора слов и чисел, и в строке может быть более одного многозначного числа.

Единственное место, где я обычно это делал, - это Finder в Mac OS, который сортирует имена файлов, содержащие смешанные числа и слова, естественно, ставя «20» после «3», а не перед ним.

Требуемый порядок сортировки будет создаваться алгоритмом, который разбивает каждую строку на блоки по границам букв и цифр, а затем упорядочивает каждую часть, обрабатывая буквенные блоки с обычным сопоставлением и числовые блоки как целые числа для целей сопоставления. Так:

'AAA2fred' станет('AAA',2,'fred') а также'AAA10bob' станет('AAA',10,'bob'), Затем они могут быть отсортированы по желанию:

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)

по сравнению с обычным порядком сортировки строк:

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

Однако подход сравнения записей не обобщается, поскольку Pg не будет сравнивать конструкции ROW (..) или записи с неодинаковым количеством записей.

Учитывая данные образцав этом SQLFiddle сортировка по умолчанию en_AU.UTF-8 производит порядок:

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

но я хочу:

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

В данный момент я работаю с PostgreSQL 9.1, но предложения только для 9.2 подойдут. Меня интересуют советы о том, как создать эффективный метод разделения строк и как сравнить полученные итоговые данные в описанном порядке чередования строк и чисел. Или, конечно, на совершенно разных и лучших подходах, которые не требуют разделения строк.

PostgreSQL, похоже, не поддерживает функции компаратора, иначе это можно сделать довольно легко с помощью рекурсивного компаратора и чего-то вродеORDER USING comparator_fn иcomparator(text,text) функция. Увы, этот синтаксис мнимый.

Обновить: Сообщение в блоге по теме.

Ответы на вопрос(6)

Ваш ответ на вопрос