2016-10-03 5 views
0

В системе я работаю с имеет систему нумерации, где числа 0-999 представлены обычным 0-999, но 1000 представлена ​​, а затем A01, A02, A03 и т.д., 1100 быть B00 и т.д.заказ порядковый номер форматирования

Я не могу придумать способ справиться с этим в T-SQL, не прибегая к проверке отдельных цифр с помощью огромных аргументов case, и должен быть лучший способ. Я думал об использовании шестнадцатеричного кода, но это неправильно.

DECLARE @startint int = 1, 
     @endint int = 9999; 

;WITH numbers(num) 
AS 
(
    SELECT @startint AS num 
    UNION ALL SELECT num+1 FROM numbers 
    WHERE num+1 <= @endint 
) 
SELECT num, convert(varbinary(8), num) FROM [numbers] N 
OPTION(MAXRECURSION 0) 

С этим 999 теперь 3E7, где это должно быть просто 999.

Это в настоящее время производит это:

Number Sequence 
0   0x00000000 
1   0x00000001 
... 
10  0x0000000A 
... 
100  0x00000064 
... 
999  0x000003E7 
1000  0x000003E8 

Что я ищу:

Number Sequence 
0   000 
1   001 
... 
10  010 
11  011 
12  012 
... 
999  999 
1000  A00 
1001  A01 
... 
1099  A99 
1100  B00 
1101  B01 
1200  C00 

мне это нужно для работы в SQL Server 2008.

+0

Можете ли вы показать ваши ожидаемые выходные и текущие данные – TheGameiswar

+0

SQL Server уже есть [последовательности] (https://msdn.microsoft.com/en-us/library/ff878058.aspx). Эта рекурсивная версия на самом деле является одним из самых медленных способов генерации таблицы чисел, а не способом генерации следующего числа в последовательности. Наконец, ваша проблема заключается не в опрокидывании (вы вообще не перевертываетесь), это вопрос форматирования числа для строки –

+0

@PanagiotisKanavos не беспокоится о том, как быстро или медленно это происходит. Система была написана, когда люди были новыми для кодирования, поэтому на самом деле есть таблица, в которой хранится все это ... * cringe * ... но это означает, что я должен вставить его и больше не беспокоиться об этом. – Logan

ответ

0

Вы можете использовать целочисленное деление и по модулю, чтобы отделить сотни частей от десятков. После этого вы можете добавить 64 к частному, чтобы получить значение ASCII, начиная с A.

create function function dbo.fn_NumToThreeLetters(@num integer) 
RETURNS nchar(3) 
AS 
begin 
RETURN (SELECT (case 
        when @num/1000 >0 then 
         CHAR(((@num-900)/100) +64) 
         + replace(cast(@num %100 as nchar(2)),' ','0') 
        else cast(@num as nvarchar(3)) 
       end) 
     ) 
END 

select dbo.fn_NumToThreeLetters(1100) 
------- 
B00 

select dbo.fn_NumToThreeLetters(999) 
------- 
999 

Первый when пункт гарантирует, что преобразование применяется только тогда, когда число превышает 1000. Если вычесть 900 затем разделить на 100, таким образом, мы получим число, которое начинается с 1 на 1000, 2 для 1100 и т. Д.

Добавить 64 к нему, чтобы получить ASCII, начиная с A и преобразовать его обратно в символ с CHAR.

Остальная часть должна быть преобразована в 2-значный nchar, где пробелы заменены на 0.

Это будет работать только до 3500. Вопрос не определяет, что должно быть сделано с большим числом

+0

Spec специфицирует только значения до 'Y99', поэтому это отлично работает, спасибо. – Logan

Смежные вопросы