За последние 24 часа нас посетили 22475 программистов и 1147 роботов. Сейчас ищут 704 программиста ...

Натуральная сортировка

Тема в разделе "MySQL", создана пользователем tommyangelo, 23 ноя 2011.

  1. tommyangelo

    tommyangelo Старожил

    С нами с:
    6 дек 2009
    Сообщения:
    2.549
    Симпатии:
    0
    Адрес:
    Мариуполь
    Есть таблица, в числе столбцов которой есть значения диапазонов версий.

    Код (Text):
    1. version        version_range
    2. 2.3.1.800     2.3.1.1025
    3. 2.3.1.2000   2.3.1.2500
    4. 3.5.1.100     3.5.1.200
    И т.д.
    Мне приходит версия, для которой необходимо выбрать все строки, попадающие в диапазон.

    Пример - пришла версия 2.3.1.1000
    Попадает в первый диапазон.

    Каким запросом мы можем получить все строки с диапазонами, подходящими под мою версию?

    Варианты моего решения
    1) С ходу лезущий в голову BETWEEN
    [sql]SELECT * FROM table WHERE '2.3.1.1000' BETWEEN version AND version_range[/sql]
    Работать естественно не будет, так как при сортировке строк 2.3.1.800 стоит ниже чем 2.3.1.1025

    2) Первое, что нагуглил по запросу "натуральная сортировка" - приведение к числовому типу.
    [sql]SELECT * FROM table WHERE '2.3.1.1000' + 0 BETWEEN version + 0 AND version_range + 0[/sql]
    Работать также не будет - отбросится полностью "дробная" часть (а именно она и важна)
    [sql]SELECT '2.3.1.1000' + 0 [/sql] возвращает просто 2

    3) Костыльное решение- убрать все точки, и сравнить как числа
    [sql]SELECT * FROM table WHERE REPLACE('2.3.1.1000', '.', '' )+ 0 BETWEEN REPLACE(version, '.', '' )+ 0 AND REPLACE(version_range, '.', '' )+ 0;[/sql]
    Работать будет только если во всех версиях одинаковое число знаков
    Код (Text):
    1. 2.3.1.800     => 231800
    2. 2.3.1.2000   => 2312000
    3. 3.5.1.100     => 351100
    Второе и третье числа меняются местами, а этого быть не должно

    Вытащить в php и сравнить через version_compare - плохой вариант. В таблице несколько десятков тысяч записей.

    Я в тупике, может кто сталкивался?
     
  2. topas

    topas Активный пользователь

    С нами с:
    16 авг 2006
    Сообщения:
    2.258
    Симпатии:
    36
  3. tommyangelo

    tommyangelo Старожил

    С нами с:
    6 дек 2009
    Сообщения:
    2.549
    Симпатии:
    0
    Адрес:
    Мариуполь
    SUBSTRING_INDEX мог бы подойти, но мажорные версии тоже нужно учитывать.

    А за ссылку спасибо, там есть идея приводить всё к строкам типа
    Код (Text):
    1.  
    2. 2.3.1.800     => 0002.0003.0001.0800
    3. 2.3.1.2000    => 0002.0003.0001.2000
    4. 3.5.1.100     => 0003.0005.0001.0100
    Мне кажется, рациональное зерно тут есть)
     
  4. topas

    topas Активный пользователь

    С нами с:
    16 авг 2006
    Сообщения:
    2.258
    Симпатии:
    36
  5. tommyangelo

    tommyangelo Старожил

    С нами с:
    6 дек 2009
    Сообщения:
    2.549
    Симпатии:
    0
    Адрес:
    Мариуполь
    не-а, у него ограничение для каждого разряда - 256

    В принципе уже реализовал перевод в 0003.0005.0001.0100 - обернул в хранимую функцию.