MySQL сортировка номеров версий - PullRequest
16 голосов
/ 22 сентября 2011

У меня есть такие значения, как:

1.1.2 
9.1 
2.2
4
1.2.3.4
3.2.14
3.2.1.4.2
.....

Мне нужно отсортировать эти значения, используя mysql. Тип данных для этого - varbinary (300).

Желаемый результат будет выглядеть так:

1.1.2
1.2.3.4
2.2
3.2.1.4.2
3.2.14
4
9.1

Запрос:

select version_number from table order by version_number asc 

не дает правильного порядка сортировки.

Желаемый результат этого:

1.1.2
1.2.3.4
2.2
3.2.1.4.2
3.2.14 
4
9.1

Номера версий могут содержать до 20 цифр (например, 1.2.3.4.5.6.7.8.9.2.34) и более. Конкретный максимальный размер отсутствует, а стандартная версия такая же, как указано выше.

Ответы [ 3 ]

36 голосов
/ 07 декабря 2011

Попробуйте использовать функцию INET_ATON для сортировки следующим образом:

SELECT version_number FROM table ORDER BY INET_ATON(SUBSTRING_INDEX(CONCAT(version_number,'.0.0.0'),'.',4))

Этот трюк был первоначально размещен в списке рассылки mysql , так что огромное спасибо оригинальному постеру, Майклу Стассену!

Вот что он должен был сказать:

Если каждая часть не больше 255, вы можете использовать INET_ATON (), чтобы сделать что хочешь (до 4-й части). Трюк делает каждый из этих сначала посмотрите на IP, используя CONCAT для добавления 0.0.0, чтобы убедиться, что каждый В строке есть как минимум 4 части, затем SUBSTRING_INDEX, чтобы вытащить только первые 4 части.

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

В последнем случае он рекомендует решение, аналогичное решению, опубликованному @spanky (отдельные столбцы).

5 голосов
/ 22 сентября 2011

Я бы сохранил его в трех отдельных столбцах, по одному для каждой части номера версии.

Сделайте каждый столбец TINYINT и даже создайте индекс по 3 столбцам.Это должно упростить задачу.

Тогда вы можете сделать: select CONCAT(v1,'.',v2,'.',v3) AS version_number FROM table ORDER BY v1 asc, v2 asc, v3 asc

0 голосов
/ 17 января 2017

Если вы хотите поддерживать такие версии, как 1.1-beta или использовать старые версии MySql без INTE_ATON, вы можете получить такой же сорт, разделив версию и отсортировав каждую часть в виде целого числа и строки:

SELECT
    version,
    REPLACE(SUBSTRING(SUBSTRING_INDEX(version, '.', 1), LENGTH(SUBSTRING_INDEX(version, '.', 1 - 1)) + 1), '.', '') v1,
    REPLACE(SUBSTRING(SUBSTRING_INDEX(version, '.', 2), LENGTH(SUBSTRING_INDEX(version, '.', 2 - 1)) + 1), '.', '') v2,
    REPLACE(SUBSTRING(SUBSTRING_INDEX(version, '.', 3), LENGTH(SUBSTRING_INDEX(version, '.', 3 - 1)) + 1), '.', '') v3,
    REPLACE(SUBSTRING(SUBSTRING_INDEX(version, '.', 4), LENGTH(SUBSTRING_INDEX(version, '.', 4 - 1)) + 1), '.', '') v4
FROM 
    versions_table
ORDER BY
    0+v1, v1 DESC, 0+v2, v2 DESC, 0+v3, v3 DESC, 0+v4, v4 DESC;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...