Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 General SQL Server Forums
 New to SQL Server Programming
 Comparing alphanumerics. Here's a challenge.

Author  Topic 

DavidChel
Constraint Violating Yak Guru

474 Posts

Posted - 2008-10-28 : 17:44:40
My ERP system has a Char field which contains job "numbers". They set this field to be CHAR because they only allocated 4 digits for the "numbers". So, they use an alphanumeric field which holds 0-9,A-Z. They allow you to set the "alpha number" which represents how many digits from the right are only numeric. They provide the following chart:

Alpha
number Job range Base calculation Jobs available
1 I000A-IZZZZ 34^4th power 1,336,336
2 I00A0-ZZZ9 34^3rd power x 10 393,040
3 I0A00-IZZ99 34^2nd power x 100 115,600
4 IA000-IZ999 34 x 1000 34,000



All these numbers start with an 'I' so the first character can be ignored. The reason they indicate 34 instead of 36 is because the documentation indicates that 'I' and 'T' are skipped. However, through testing I found that they aren't. The ERP company admitted the error in their documentation.

So, because numbers are alphabetically before letters, I can determine which is the last Job Order assigned with a simple Order By statement, right? However, here is my question. Let's say a company was using Alpha Number 4 so the last "number" they could use was IZ999. If the last one assigned was IC549, how could I determine how many "numbers" were left before they hit IZ999?

Additionally, what if the system had the same last number IC549, how many would they have left until they hit IZZZZ?



Lamprey
Master Smack Fu Yak Hacker

4614 Posts

Posted - 2008-10-28 : 18:40:30
for number #4 that math seems wrong. I think you can ony have 26000 jobs available (26 x 1000).

26000 - (((3 - 1) * 1000) + 549 + 1) = 23450

1. (3 - 1) -- This is the numeral equivalient for the letter (C = 3) Subtract one since we are starting at 0.
2. Multiply by 1000 to adjust the number over 3 digits.
3. Add 1 to the Numeric portion of the Job Nummber to get the correct offset.
4. Then subtract it all from the total possible number of Jobs.


Go to Top of Page

DavidChel
Constraint Violating Yak Guru

474 Posts

Posted - 2008-10-29 : 08:44:35
In my post, you'll notice why they used 34.

quote:
The reason they indicate 34 instead of 36 is because the documentation indicates that 'I' and 'T' are skipped. However, through testing I found that they aren't. The ERP company admitted the error in their documentation.


The number should actually be 36.

I don't think your solution applies Lamprey since there are 36 options per spot.

Anybody?
Go to Top of Page

hanbingl
Aged Yak Warrior

652 Posts

Posted - 2008-10-29 : 10:36:07
David, wouldn't this be a 36 base from 0-9, A-Z? can there be any combination such that an alpha is after a numeric.
Go to Top of Page

Lamprey
Master Smack Fu Yak Hacker

4614 Posts

Posted - 2008-10-29 : 11:54:29
quote:
Originally posted by DavidChel

In my post, you'll notice why they used 34.

quote:
The reason they indicate 34 instead of 36 is because the documentation indicates that 'I' and 'T' are skipped. However, through testing I found that they aren't. The ERP company admitted the error in their documentation.


The number should actually be 36.

I don't think your solution applies Lamprey since there are 36 options per spot.

Anybody?

Ok then change it to 24000 then. How can you go from A - Z skipping I and T and get 34? Or is the Job Range example incorrect?

Again, I'm just talking about #4.
Go to Top of Page

DavidChel
Constraint Violating Yak Guru

474 Posts

Posted - 2008-10-29 : 12:39:36
I'm sorry, I tried to abbreviate the description hoping to make it easier for you guys. Ok, here is how it works (and how you get 36 possible options per digit):

quote:
Job order number sequencing is based on a mathematical system known as base 36 numbering. In base 36:

Letters are inserted beginning in the right-most column (i.e., column 1) and moving to the left as the value is incremented.
This expands the available number of characters per column from 10 (0-9) to 36 (0-9 followed by A-Z).
It is then possible to generate many unique document numbers in sequence using a limited set of only four or five digits.


Go to Top of Page

hanbingl
Aged Yak Warrior

652 Posts

Posted - 2008-10-29 : 13:25:16
here is your base 36 function


create function dbo.fn_base36(@mystr varchar(8000))
returns bigint
as
BEGIN
set @mystr = reverse(@mystr)
declare @len int, @onechar char(1), @pos int, @numvalue bigint
declare @arrystr varchar(100)
set @arrystr = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
select @len=len(@mystr)
set @onechar = ''
set @pos = 1
set @numvalue = 0
while @pos<=@len
begin
select @onechar = substring(@mystr,@pos,1)
select @numvalue = (charindex(@onechar,@arrystr)-1)*power(len(@arrystr),@pos-1)+@numvalue
set @pos = @pos + 1
end

return @numvalue
END
Go to Top of Page

DavidChel
Constraint Violating Yak Guru

474 Posts

Posted - 2008-10-29 : 14:54:40
Umm.. Can I get a little clarification? What do I do with that?
Go to Top of Page

hanbingl
Aged Yak Warrior

652 Posts

Posted - 2008-10-29 : 15:06:45
You just said
quote:
Job order number sequencing is based on a mathematical system known as base 36 numbering. In base 36:


You can use this function to convert a base 36 system to decimal (base 10) system, for example:

select dbo.fn_base36('000A')
result: 10

select dbo.fn_base36('ZZZZ')-dbo.fn_base36('C549')
result: 1113110


Go to Top of Page

DavidChel
Constraint Violating Yak Guru

474 Posts

Posted - 2008-10-29 : 16:13:24
Oh, thanks hanbingl, I get it.

Here's the kicker though, that will work for alpha number 4 where all characters are alphanumeric, but what about the other versions?

For example, if someone had alpha 2 and had the number I3CA1 and wanted to know how many numbers they had left until they hit IZZZ9?

Again, I appreciate the help so far.
Go to Top of Page

hanbingl
Aged Yak Warrior

652 Posts

Posted - 2008-10-29 : 16:37:57
That would be:

select (dbo.fn_base36('ZZZ')-dbo.fn_base36('3CA'))*10+8
Go to Top of Page

hanbingl
Aged Yak Warrior

652 Posts

Posted - 2008-10-29 : 16:42:19
let me explain:


select (dbo.fn_base36('ZZZ')*10+9) - (dbo.fn_base36('3CA')*10+1)

which according to algebra

select dbo.fn_base36('ZZZ')*10 + 9 - (dbo.fn_base36('3CA')*10 - 1

which according to algebra

select dbo.fn_base36('ZZZ')*10 - (dbo.fn_base36('3CA')*10 + 9 - 1
..
select (dbo.fn_base36('ZZZ')-dbo.fn_base36('3CA'))*10+8
Go to Top of Page

hanbingl
Aged Yak Warrior

652 Posts

Posted - 2008-10-29 : 16:48:54
Another example:

the difference between 'IC549' and 'IZZ99' (assume IZZ99 is the template indicates that the last 2 characters' always base10 decimal)


select (dbo.fn_base36('ZZ') - dbo.fn_base36('C5') ) * power(10,2) + (99-49)


where POWER(10,2) depends on the number of 9's in the template. "9" is power(10,1), "99" is Power(10,2), "999" is power(10,3)... and so on
Go to Top of Page

DavidChel
Constraint Violating Yak Guru

474 Posts

Posted - 2008-10-29 : 17:46:58
I had to read that 3 times, but I get it. Freaking genius man. Thanks.
Go to Top of Page

SwePeso
Patron Saint of Lost Yaks

30421 Posts

Posted - 2008-10-29 : 17:53:06
Beware that input parameter of 8000 chars of Z on base 36, needs 12451 characters in base 10.
Way over the BIGINT datatype.

A full BIGINT in base 10 is only 13 characters in base 36 using Z.



E 12°55'05.63"
N 56°04'39.26"
Go to Top of Page

DavidChel
Constraint Violating Yak Guru

474 Posts

Posted - 2008-10-30 : 09:23:12
quote:
Originally posted by Peso

Beware that input parameter of 8000 chars of Z on base 36, needs 12451 characters in base 10.
Way over the BIGINT datatype.

A full BIGINT in base 10 is only 13 characters in base 36 using Z.



E 12°55'05.63"
N 56°04'39.26"




I'm confused Peso. If I have 4 digits then the maximum value would be 1,679,616. Isn't that well within the BIGINT data type?
Go to Top of Page

hanbingl
Aged Yak Warrior

652 Posts

Posted - 2008-10-30 : 10:37:07
There is a flaw in the function but it'll suit for your environment. I should change varchar size to (6) and return 0 when there's no inputs.
Go to Top of Page

DavidChel
Constraint Violating Yak Guru

474 Posts

Posted - 2008-10-30 : 15:13:00
I was trying to use this without creating a function with the following:


Declare @mystr varchar(8000)

set @mystr = 'C549'

set @mystr = reverse(@mystr)

declare @len int, @onechar char(1), @pos int, @numvalue bigint
declare @arrystr varchar(100)
set @arrystr = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
select @len=len(@mystr)
set @onechar = ''
set @pos = 1
set @numvalue = 0
while @pos<=@len
begin
select @onechar = substring(@mystr,@pos,1)
select @numvalue = (charindex(@onechar,@arrystr)-1)*power(len(@arrystr),@pos-1)+@numvalue
set @pos = @pos + 1
end

select @numvalue


This works. However, when I try using another query to return the value for @mystr and use the following code:

DECLARE @mystr varchar(8000)

SET @mystr = (SELECT S.fcnumber FROM m2mdata02.dbo.sysequ S WHERE fcprompt = 'Next Internal J.O. Number')

SET @mystr = reverse(@mystr)

DECLARE @len int, @onechar char(1), @pos int, @numvalue bigint

DECLARE @arrystr varchar(100)

SET @arrystr = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'

SELECT @len=len(@mystr)

SET @onechar = ''

SET @pos = 1

SET @numvalue = 0

WHILE @pos<=@len
BEGIN
SELECT @onechar = substring(@mystr,@pos,1)
SELECT @numvalue = (charindex(@onechar,@arrystr)-1)* power(len(@arrystr),@pos-1)+@numvalue
SET @pos = @pos + 1
END

SELECT @numvalue


I get an arithmetic overflow error for type int. I don't understand
why when this returns a single value.

SELECT S.fcnumber FROM m2mdata02.dbo.sysequ S WHERE fcprompt = 'Next Internal J.O. Number'


Anybody?

Go to Top of Page

hanbingl
Aged Yak Warrior

652 Posts

Posted - 2008-10-30 : 15:29:53
When you select fcnumber, what does it show exactly? any trailing spaces?
Go to Top of Page

DavidChel
Constraint Violating Yak Guru

474 Posts

Posted - 2008-10-30 : 16:33:31
I think there may be trailing spaces.
Go to Top of Page

hanbingl
Aged Yak Warrior

652 Posts

Posted - 2008-10-30 : 16:44:33
okay,

SET @mystr = reverse(rtrim(ltrim(@mystr)))
Go to Top of Page
    Next Page

- Advertisement -