Получение столбца MAX int, но избегающий естественного порядка MySQL

#mysql #sorting #max

#mysql #сортировка #макс

Вопрос:

Мне нужно получить самую большую запись с номером листа из таблицы сервисов:

 services
  - id 
  - folio (int)
  

Номер фолио — это столбец Int, образованный year incremental number . Каждый раз, когда вставляется запись, номер листа формируется путем the_current_year (max folio found 1) указания этого, это примерный список доступных листов:

 20191
...
2019124
2019125
20201
20202
...
202019
  

Согласно примерному списку, на данный момент у меня было бы 125 сервисов на 2019 год и 19 сервисов на 2020 год. Пожалуйста, обратите внимание, что при каждом изменении года последние цифры номера фолио снова начинаются с 1.

Здесь я сталкиваюсь с 2 проблемами. Обработка его как целого числа и получение MAX по folio не сработает, потому что естественный порядок сортировки. Это вернет наибольшее значение int.

Таким образом, выполнение: SELECT MAX(folio) FROM services LIMIT 1; возвращает 2019125 , когда мне действительно нужно получить 202019

Обработка его как varchar также не сработает, поскольку он будет упорядочен по char: SELECT MAX(CONVERT(folio, CHAR(50))) FROM services LIMIT 1; возвращает 20202 вместо 202019

Итак, мой вопрос в том, как получить последний номер фолио?

Комментарии:

1. Каков ваш ожидаемый результат? Вам нужен максимальный объем за каждый год или только максимальный объем за все строки?

2. Ваше решение — это именно то, чего я ожидал, получая максимальное количество строк.

Ответ №1:

Это сделает это:

 SELECT folio
FROM services
ORDER BY LEFT(folio, 4) DESC, SUBSTR(folio, 5)   0 DESC 
LIMIT 1
  

В MySQL вы можете обрабатывать целые числа как строки и применять такие функции, как LEFT() и SUBSTR() .
Применяя 0 к строке, строка неявно преобразуется в число.
Смотрите демонстрацию.
Результаты:

 | folio  |
| ------ |
| 202019 |
  

Ответ №2:

Вам было бы лучше иметь год и серийный номер в отдельных столбцах. Вы можете разделить их в запросе:

 SELECT folio
FROM (
  SELECT 
    CAST(substring(folio, 1,4) AS UNSIGNED) as 'year', 
    CAST(substring(folio, 5) AS UNSIGNED) as 'service_no',
    folio
  FROM services
ORDER BY year DESC, service_no DESC
limit 1
) AS q; 
  

Смотрите db-fiddle

Комментарии:

1. ваша скрипка возвращает 2019125 вместо 202019 , поэтому она работает не так, как ожидалось.

2. Исправлена ошибка @Luciano