PostgreSQL порядок по выпуску-естественный сортировка

у меня есть Postgres ORDER BY проблема со следующей таблицей:

em_code  name
EM001    AAA
EM999    BBB
EM1000   CCC

вставить новую запись в таблице

  1. я выбираю последнюю запись с SELECT * FROM employees ORDER BY em_code DESC
  2. полосы алфавитов из em_code usiging reg exp и хранить в ec_alpha
  3. приведите рематирующую часть к integer ec_num
  4. увеличивается ec_num++
  5. Pad с достаточным zeors и префиксом ec_alpha опять

, когда em_code достигает EM1000, вышеуказанный алгоритм терпит неудачу.

первый шаг вернет EM999 вместо EM1000, и он снова будет генерировать EM1000 как новый em_code, нарушив ограничение уникального ключа.

любая идея, как выбрать EM1000?

6 ответов


причина в том, что строка сортируется в алфавитном порядке (а не численно, как вы хотели бы) и 1 сортируется до 9. Вы могли бы решить его следующим образом:

SELECT * FROM employees ORDER BY substring(em_code, 3)::int DESC

было бы более эффективно отбросить избыточные " EM " из вашего em_code - Если вы можете и сохранить целое число для начала.


дополнительный ответ на вопрос в комментарий

чтобы удалить все не-цифры из строки:

SELECT regexp_replace(em_code, E'\D','','g')
FROM employees

\D - это регулярное выражение класс-стенография для "без цифр".
'g' поскольку 4-й параметр является" глобальным " переключателем для применения замены к каждому вхождению в строке, а не только к первому.

поэтому я заменяю каждую не-цифру пустой строкой, перегоняя только цифры из строки.


вы можете использовать только эту строку "ORDER BY length (substring (em_code FROM' [0-9]+')), em_code"


Это всегда возникает в вопросах и в моем собственном развитии, и я, наконец, устал от сложных способов сделать это. Я, наконец, сломался и реализовал его как расширение PostgreSQL:

https://github.com/Bjond/pg_natural_sort_order

Это бесплатно использовать, лицензия MIT.

в основном это просто нормализует цифры (нулевые предварительные цифры) в строках, так что вы можете создать столбец индекса для полноскоростной сортировки au naturel. Этот readme объясняет.

преимущество заключается в том, что вы можете иметь триггер для работы, а не код приложения. Он будет рассчитан на Машинной скорости на сервере PostgreSQL, и миграции, добавляющие столбцы, станут простыми и быстрыми.


Я писал об этом подробно в этот вопрос:

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

(Я публикую этот ответ только как полезную перекрестную ссылку, поэтому это Вики сообщества).


Я подумал о другом способе сделать это, который использует меньше памяти db, чем заполнение и экономит время, чем расчет на лету.

https://stackoverflow.com/a/47522040/935122

Я также поставил его на GitHub

https://github.com/ccsalway/dbNaturalSort


один подход, вы можете создать naturalsort функции для этого. Вот пример, написанный легендой Postgres RhodiumToad.

create or replace function naturalsort(text)
    returns bytea language sql immutable strict as $f$
    select string_agg(convert_to(coalesce(r[2], length(length(r[1])::text) || length(r[1])::text || r[1]), 'SQL_ASCII'),'\x00')
    from regexp_matches(, '0*([0-9]+)|([^0-9]+)', 'g') r;
$f$;

источник:http://www.rhodiumtoad.org.uk/junk/naturalsort.sql

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

SELECT * FROM employees ORDER BY naturalsort(em_code) DESC