Як на mysql коректно сортувати рядок з числами

  • MySQL

Доброго вам дня. У розробці одного магазину зіткнувся з проблемою неправильної сортування товарів по імені, якщо у них в назві присутнє число.

Що мається: база даних MySQL і таблиця products з полем name.

У назві товарів може бути присутнім кілька чисел і всі вони можуть знаходиться в різних місцях рядка. Ось приклад:

При стандартній сортування (ORDER BY name ASC) я отримую наступний список:

Товари упорядковано за першими літерами, які до цифр, а потім йде класична строкова сортування чисел: 13, 16, 9 і 10, 14, 9. Порівняння відбувається тільки по першій цифрі, тому 9 виявляється після 10 і вище.

У чому проблема: в тому, що ці числа можуть знаходиться в будь-якому місці рядка, вони можуть бути в напівкруглих дужках, чи ні. Оскільки числа в назві товару можуть знаходиться де завгодно, то відпадають всі варіанти з SUBSTRING_INDEX. Так само мені навіть в голову не приходить, чи зможуть тут допомогти регулярні вирази. Виходить, що потрібно створити сортування, яка буде по-черзі брати кожне слово після пробілу і порівнювати його як рядок або як число.

На даний момент я вирішив питання, як мені здається, звірячим милицею. При вибірці товару я зробив вирізку дужок і створив ще одну змінну name_order - це щоб в майбутньому не довелося ще раз позбавлятися від дужок:

Далі я створив функцію SPLIT_STR. яка буде різати змінну по пропуску. Ну і останнє, і найстрашніше - це розрізання назви товару на окремі слова і числа, приведення кожного елемента цього "масиву" до числа через CAST, і як наслідок, сортування по величезній кількості змінних:

Як видно з коду, я розрізав назву на 12 елементів по пропуску, потім по черзі порівняв кожен елемент як число і як рядок. З такою сортуванням все працює ідеально, ось тільки на цей код боляче дивитися.

Увага питання: може бути у когось є більш коректне і адекватне рішення задачі? Власний досвід або хоча б думки, як зробити такий же функціонал, але більш акуратно і красиво?

Буду вдячний за будь-які думки! І заранее спасибо))