#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