PostgreSQL порядок по выпуску-естественный сортировка
у меня есть Postgres ORDER BY
проблема со следующей таблицей:
em_code name
EM001 AAA
EM999 BBB
EM1000 CCC
вставить новую запись в таблице
- я выбираю последнюю запись с
SELECT * FROM employees ORDER BY em_code DESC
- полосы алфавитов из em_code usiging reg exp и хранить в
ec_alpha
- приведите рематирующую часть к integer
ec_num
- увеличивается
ec_num++
- 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
один подход, вы можете создать 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