получить следующую максимальную проблему с A999> A1000 - PullRequest
4 голосов
/ 27 августа 2010

Некоторые серийные номера продуктов относятся к типу varchar и имеют букву, обозначающую тип, за которым следует число.Числа от 0 дополняются до 5 цифр, и мы приближаемся к «A100000».

Для букв, которые содержат менее 100000 элементов, они по-прежнему хотят 0, дополняющих до 5 цифр, и букв, которые имеют более 100000чтобы иметь больше цифр вплоть до любого номера.

В настоящее время текущий максимальный серийный номер находит примерно так:

SELECT MAX(SerialNumber) FROM Table WHERE LEFT(SerialNumber, 1) = @leadingChar

Однако при использовании этого метода выбирается «A99999».A100000 ', потому что 9> 1.(По той же причине, что Zoo следует за Apple в словаре, больше символов, но меньше значения в начальном символе.)

Таким образом, проблема заключается в том, когда он увеличивает текущий максимальный серийный номер для получения следующего серийного номера после 'A99999'каждый раз, когда вы получаете новый серийный номер, вы получаете «A100000».

Разделять их на столбцы типа char и столбец int в базе данных будет громоздко, поскольку он используется в нескольких таблицах, а их несколько миллионов.Всего серийных номеров.

Он написан как веб-приложение в базе данных vbscript / classic asp SQL Server 7.

Если есть лучшие теги / заголовки, не стесняйтесь редактировать / дайте мне знать.

Спасибо за любую помощь.

Ответы [ 3 ]

4 голосов
/ 27 августа 2010

Вы можете рассмотреть возможность применения подхода, описанного Мэттом Гибсоном в комментариях к публикации Coding Horror о порядке естественной сортировки.

Как разработчик хранилища данных, янет ничего странного в том, как деловые люди ожидают увидеть вещи отсортированными, и это никогда не ASCII ... Одна вещь, которую я делаю, это добавлять дополнительные столбцы в мои базы данных и вставлять «исправленные» версии ключей, которые я использую, поэтому моя таблицаможет выглядеть так:

Customer Number|Customer|SortKey1
MS948|Fred Smith|MS00000948
MS9215|John Star|MS00009215

.., что означает, что я могу использовать стандартную сортировку ASCII SQL (индексируется по скорости, если это необходимо), а не копаться в чем-либо в клиентских приложениях.Клиент представляет пользователю реальный ключ, но сортирует его по предварительно рассчитанному ключу, безопасному для сортировки ASCII, и мне нужно выполнить тяжелую работу только один раз, заранее.

Это может означать, чтодобавление дополнительного поля к текущей таблице, которое будет использоваться только для генерации ключа.Код «получить следующий ключ» будет ссылаться на новое поле, но также заполнит существующее поле, чтобы большую часть кода и данные с внешним ключом можно было оставить как есть.

Вы также можете рассмотретьс помощью оператора SQL LIKE найти MAX, если в поле SerialNumber есть индекс.Размещенный вами код может не использовать индекс, так как вы применяете функцию к полю в предложении WHERE (я не знаком с подробностями оптимизации запросов SQL Server 7, поэтому не могу сказать наверняка).

3 голосов
/ 27 августа 2010

Вы можете попробовать это, чтобы получить наибольшее число для главного персонажа:

SELECT MAX(CAST(SUBSTRING(SerialNumber, 2, 99) AS INT))
FROM Table1
WHERE LEFT(SerialNumber, 1) = @leadingChar

Это будет медленно, так как он не сможет использовать индекс, чтобы найти максимальное число. Было бы лучше разделить его на две колонки, как вы упомянули в вопросе. Может быть неловко вносить изменения, но это поможет вам в будущем.

2 голосов
/ 29 августа 2010

Если вы обнаружите, что ваше решение недостаточно продуктивно и вам нужно более быстрое решение, требующее минимальных изменений приложения, вы можете попробовать это:

Создайте в своей таблице два столбца, SerialLetter и SerialNumber.

Затем заполните их следующим образом:

UPDATE Table SET 
SerialLetter = SUBSTRING(Serial, 0, 1), 
SerialNumber = SUBSTRING(Serial, 1, 99)

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

Затем создайте триггеры обновления и вставки, чтобы любые серийные номера в таблице были отражены в ваших новых столбцах.

Затем создайте индекс для SerialLetter и SerialNumber в этомпорядок.(один индекс на два столбца)

Тогда вы можете

SELECT MAX(SerialNumber) WHERE SerialLetter = 'X'

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...