Reputation: 5761
I have a rather silly question about SQL Server. I am trying to store a BigInt in SQL Server, and figure that I can convert it to a string before inserting it into a Nvarchar(Max)
-style field.
However, I need to run a SELECT
statement against that column, and as it's a string, I am not sure how to evaluate it. I am aware that strings in some languages do evaluate numerically, such that '234234' is considered lesser than '2342545345344'. Would it be possible to do something similar here?
Edit: Blast, I'm an idiot. I meant to say C#'s BigInteger, which can hold values much larger than SQL's BigInt.
Upvotes: 1
Views: 846
Reputation: 91
It seems like you are looking for how to sort these in order?
If you have a trimmed text string that is only "0-9" and prefixed with "-" when negative, then you can use the below to do a character-based sort. Numbers with fewer digits are padded, and negative numbers are translated to an inversely sorted character set. Note, you need to have a conceptual "maximum length".
DECLARE @maxlen INT = 1000
DECLARE @abc123 TABLE (NumericString VARCHAR(1000)) --e.g. "Big Integer"
INSERT INTO @abc123
SELECT '123'
UNION ALL SELECT '-123'
UNION ALL SELECT '1789'
UNION ALL SELECT '2345'
UNION ALL SELECT '-3490'
UNION ALL SELECT '-6888'
UNION ALL SELECT '-1000000'
UNION ALL SELECT '0'
SELECT aa.NumericString FROM @abc123 aa
CROSS APPLY (SELECT REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( REPLACE(
aa.NumericString,'0','z'),'1','y'),'2','x'),'3','w'),'4','v'),'5','u'),'6','t'),'7','s'),'8','r'),'9','q') [translatedDesc]
) ss --todo: you can use TRANSLATE() here if you have the option.
CROSS APPLY (SELECT
CASE WHEN LEFT(aa.NumericString,1) = '-' THEN
CONCAT('-',
REPLICATE('z',@maxlen-LEN(aa.NumericString)-1),
REPLACE(ss.translatedDesc,'-','') ) --each character is translated to a character subset where a negative 0-9 would sort in reverse order, while SQL server sorts "ASC"
ELSE
CONCAT('_', -- a "positive" indicator that sorts higher than '-' or '0'
REPLICATE('0',@maxlen-LEN(aa.NumericString)),
aa.NumericString)
END [string2]
) uu
ORDER BY
uu.string2 COLLATE Latin1_General_BIN2 ASC
Upvotes: 0
Reputation: 239636
What type of SELECT
will you be performing? As a quick first step (assuming all values are positive, and stored as a sequence of digits (no scientific notation or sign symbols)), you can compare the length of the two strings.
The shorter string is the lesser of the two. If the two strings are the same length, then the lesser string (alphabetically) is the lesser numerically.
So, to output 0
for a
is less than b
, 1
for equal, 2
for a
being greater than b
:
CASE
WHEN LEN(a) < LEN(b) THEN 0
WHEN LEN(a) > LEN(b) THEN 2
WHEN a < b THEN 0
WHEN a > b THEN 2
ELSE 1
END
Upvotes: 1