Postgresql сортировка смешанных буквенно-цифровых данных - PullRequest
9 голосов
/ 11 августа 2011

Выполнение этого запроса:

select name from folders order by name

возвращает эти результаты:

alphanumeric
a test
test 20
test 19
test 1
test 10

Но я ожидал:

a test
alphanumeric
test 1
test 10
test 19
test 20

Что здесь не так?

Ответы [ 6 ]

19 голосов
/ 11 августа 2011

Вы можете просто привести name столбец к bytea типу данных, позволяющему упорядочить без учета сортировки:

SELECT name
FROM folders
ORDER BY name::bytea;

Результат:

     name     
--------------
 a test
 alphanumeric
 test 1
 test 10
 test 19
 test 20
(6 rows)
5 голосов
/ 04 сентября 2015

Все эти методы отсортировали мой выбор в алфавитном порядке:

test 1
test 10
test 2
test 20

Это решение сработало для меня (lc_collate: 'ru_RU.UTF8'):

SELECT name
FROM folders
ORDER BY SUBSTRING(name FROM '([0-9]+)')::BIGINT ASC, name;

test 1
test 2
test 10
test 20
5 голосов
/ 11 августа 2011

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

SELECT * FROM sort_test
ORDER BY SUBSTRING(text FROM '^(.*?)( \\d+)?$'),
         COALESCE(SUBSTRING(text FROM ' (\\d+)$')::INTEGER, 0);

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

Хорошо сработало в моем тесте.

Обновление исправило сортировку только по строкам с помощью простого объединения (duh).

2 голосов
/ 28 февраля 2012

Ответ OverZealous помог мне, но не сработал, если строка в базе данных начиналась с цифр, за которыми следовали дополнительные символы.

У меня сработало следующее:

SELECT name
FROM folders
ORDER BY
COALESCE(SUBSTRING(name FROM '^(\\d+)')::INTEGER, 99999999),
SUBSTRING(name FROM '^\\d* *(.*?)( \\d+)?$'),
COALESCE(SUBSTRING(name FROM ' (\\d+)$')::INTEGER, 0),
name;

Вот этот:

  1. Извлекает первое число в строке или использует 99999999.
  2. Извлекает строку, которая следует за возможным первым числом.
  3. Извлекает конечный номер или использует 0.
0 голосов
/ 17 октября 2017

Ответ Vlk выше мне очень помог, но он сортировал элементы только по числовой части, которая в моем случае была второй.Мои данные были как (стол 1, стол 2, стол 3 ...) строковая часть, пробел и числовая часть.Синтаксис в ответе A Vlk вернул данные, отсортированные по числу, и при этом это был единственный ответ из приведенного выше, который добился цели.Однако, когда строковая часть отличалась (например, рабочий стол 3, рабочий стол 4, таблица 1, рабочий стол 5 ...), таблица 1 сначала получала бы из рабочего стола 2. Я исправил это, используя синтаксис ниже:

0 голосов
/ 11 марта 2014

Последний SQL Tor работал на меня. Однако, если вы вызываете этот код из php, вам нужно добавить дополнительные слеши.

SELECT name
FROM folders
ORDER BY
COALESCE(SUBSTRING(name FROM '^(\\\\d+)')::INTEGER, 99999999),
SUBSTRING(name FROM '^\\\\d* *(.*?)( \\\\d+)?$'),
COALESCE(SUBSTRING(name FROM ' (\\\\d+)$')::INTEGER, 0),
name;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...