Substring in tsql using length - sql

Ok, so I am tring to get the first of the last 2 digits of a number. Take for instance 12345601, I want to know if the second to last numeric is a 0. If 0 then I need it to select only the last digit of the int, if different than 0 select the last 2 digits. this is what I have :
declare #myint int
set #myint= 12345601
select case when substring(cast (#myint as varchar(50) ) , len(#myint)-1, len(#myint)-1 ) = 0 then right(#myint, 1)
else right(#myint, 2) end
Unfortunately, it isn't working and this is where:
substring(cast (#myint as varchar(50)), len(#myint)-1, len(#myint)-1 )
that substring is coming out at 01, but I need it to come out as 0. Any ideas?

Try this:
SELECT CASE WHEN LEFT(RIGHT(#myint,2),1) = 0 THEN RIGHT(#myint,1) ELSE RIGHT(#myint,2) END

Try this instead:
SELECT CAST(RIGHT(#myint,2) as int)
If you cast it as an int it should strip the leading zero anyway...
You can see it in action with the code below:
declare #myint int
set #myint= 12345601
SELECT CAST(RIGHT(#myint,2) as int)
set #myint= 12345611
SELECT CAST(RIGHT(#myint,2) as int)

Related

Separate numeric inside string variable using patindex

I have here a short problem.
i have a value like this
1/11
11/1
11/11
111/1
111/11
i'm trying to separate those value and put them into numeric variable.
let say for example i have numericvar1 and numericvar2
so in the 1st string numericvar1 will contain 1 and numericvar2 will contain 11
and so on.
i've tried it like this
SET #numericvar1= LEFT(#StrNumHolder, PATINDEX('%[0-9][^0-9]%', #StrNumHolder ))
SET #numericvar2= REPLACE(RIGHT(#StrNumHolder, PATINDEX('%[0-9][^0-9]%', #StrNumHolder )),'/','')
in this code if the first number before / is in 2 digit i got the correct output. But if the first number is in 1 digit and the next number is in 2 digit like 1/11 i got the wrong output. something like this var1 = 1 and var2 = 1
did something wrong in my code? or it is not possible? please help me.
You can use CHARINDEX to get the position of '/' then use SUBSTRING to separate the numbers. Here how you can query it:
DECLARE #nIndex INT
SELECT #nIndex = CHARINDEX('/',#StrNumHolder)
SET #numericvar1 = SELECT SUBSTRING(#StrNumHolder,1,#nIndex-1)
SET #numericvar2 = SELECT SUBSTRING(#StrNumHolder,#nIndex+1,LEN(#StrNumHolder))
Can you try something like this?
DECLARE #STRNUMHOLDER VARCHAR(20)
SET #STRNUMHOLDER='111/1'
DECLARE #pos INT
SET #pos = CHARINDEX('/', #STRNUMHOLDER)
SELECT #STRNUMHOLDER AS ORIG, LEFT(#STRNUMHOLDER, #pos-1) AS NUM1, SUBSTRING(#STRNUMHOLDER, #pos+1,99) AS NUM2

SQL query to get a result divided by 2

Given a table with column like city and cityId,Adderesses. How would i write a query that gives a list cities where cityID is only even numbers. Plz explain in details.
Use the modulo operator
select * from your_table
where mod(cityID, 2) = 0
You can detect whether a number is even with the module operator (%), which gives the remainder after division by 2:
select * from your_table where cityID % 2= 0
The above query will give all the rows in which the cityID is divisible by 2
If you are interested in mod then it would be
select 6%2 -- results for this is 0
if you would want to select a number divided by 2 it will always return 0 for the perfect devisors.
if want the division the use the normal / operator as below
eg select 6/3
I used a slightly different approach. this is an event if you want a result of a zero or 1 if perfect divisor and zero otherwise
So my script is something like this
select case when #value<2 then 0 when #value%2 =0 then 1 else 0 end as myresult;
An example is as below for validating numbers between 1 and 20. You could amend it to fit your purpose
begin
declare #a int,#b int
set #a=1;
set #b = 20
while #a<=#b
begin
declare #value int
set #value =#a
select #value as myval, case when #value<2 then 0 when #value%2 =0 then 1 else 0 end
as myresult;
set #a=#a+1;
end
end

ISNUMERIC and TRY_PARSE in SQL Server [duplicate]

What is the best way to determine whether or not a field's value is an integer in SQL Server (2000/2005/2008)?
IsNumeric returns true for a variety of formats that would not likely convert to an integer. Examples include '15,000' and '15.1'.
You can use a like statement but that only appears to work well for fields that have a pre-determined number of digits...
select * where zipcode like '[0-9][0-9][0-9][0-9][0-9]'
I could write a user defined function that attempts to convert a varchar parameter to an int within a try/catch block but I'm checking with the community to see if someone has come across any succient methods to achieve this goal - preferably one that can be used within the where clause of a SQL statement without creating other objects.
Late entry that handles negative
ISNUMERIC(zipcode + '.0e0') --integer
ISNUMERIC(zipcode + 'e0') --decimal
For more see this
1 approach is
zipcode NOT LIKE '%[^0-9]%'
Double negatives, got to love 'em!
If SQL Server 2005+, I'd enable CLR and create the function to support regexes. For SQL Server 2000, see this article for creating a UDF to do the same thing.
Then I'd use the regex: ^\d{5}$
This expression gives 1 for an integer value and 0 otherwise
floor((floor(abs(zipcode)))/abs(zipcode))
Why not just use the following? I can't see to find any cases where it fails.
1 = integer
0 = not integer
null = non-numeric
DECLARE #TestValue nvarchar(MAX)
SET #TestValue = '1.04343234e5'
SELECT CASE WHEN ISNUMERIC(#TestValue) = 1
THEN CASE WHEN ROUND(#TestValue,0,1) = #TestValue
THEN 1
ELSE 0
END
ELSE null
END AS Analysis
It looks like this question needs an updated answer.
Limiting the answer to the question title:
where ISNUMERIC(zipcode) = 1
and zipcode - FLOOR(zipcode) = 0
Expounding based on the text of the question...
Currently-supported versions of SQL Server all support/include the TRY-CONVERT function.
declare #a varchar(100)
set #a = '-1.2a'
--set #a = '-1.2'
--set #a = '-1'
--set #a = '-1.0'
--set #a = '-0'
--set #a = '0'
--set #a = '1'
select #a as 'Value'
, ISNUMERIC(#a) as ISNUMERIC
, case when ISNUMERIC(#a) = 1 and #a - FLOOR(#a) = 0 then 1 else 0 end as ISINTEGER
, case when try_convert(int, #a) >= 0 and left(#a, 1) <> '-' then 1 else 0 end as ISWHOLENUMBER
, case when try_convert(int, #a) > 0 then 1 else 0 end as ISCOUNTINGNUMBER
You'll notice that TRY_CONVERT(INT, -1.0) returns NULL. So TRY_CONVERT(INT, #a) IS NOT NULL is not quite right for ISINTEGER.
case when ISNUMERIC(#a) = 1 and #a - FLOOR(#a) = 0 then 1 else 0 end as ISINTEGER
...works because if ISNUMERIC(#a) = 1 is false, FLOOR(#a) is not evaluated. Reversing the order...
case when #a - FLOOR(#a) = 0 and ISNUMERIC(#a) = 1 then 1 else 0 end as ISINTEGER
...generates an error when the value (#a) is not numeric.
So, for the case of zipcode, assuming you want to verify that a 5-digit zip code is a number and it must be 5 digits (so it can't be zero or less) and would never contain a decimal point (so you don't need to know if 12345.000 is an integer):
where try_convert(int, zipcode) > 0
and len(zipcode) = 5
I came up with the perfect answer for this on another StackO question.
It also proves you cannot use ".0e0" like one user suggests here.
It does so without CLR or non-scalar functions.
Please check it out: https://stackoverflow.com/a/10645764/555798
After moving to sql 2008, I was struggling with isnumeric('\8') returning true but throwing an error when casting to an integer. Apparently forward slash is valid currency for yen or won - (reference http://www.louiebao.net/blog/200910/isnumeric/)
My solution was
case when ISNUMERIC(#str) > 0 and not rtrim(#str) LIKE '[^0-9]%' and not rtrim(#str) LIKE '%[^0-9]' and not rtrim(#str) LIKE '[^0-9]%' then rtrim(#str) else null end
See whether the below code will help.
In the below values only 9, 2147483647, 1234567 are eligible as
Integer. We can create this as function and can use this.
CREATE TABLE MY_TABLE(MY_FIELD VARCHAR(50))
INSERT INTO MY_TABLE
VALUES('9.123'),('1234567'),('9'),('2147483647'),('2147483647.01'),('2147483648'), ('2147483648ABCD'),('214,7483,648')
SELECT *
FROM MY_TABLE
WHERE CHARINDEX('.',MY_FIELD) = 0 AND CHARINDEX(',',MY_FIELD) = 0
AND ISNUMERIC(MY_FIELD) = 1 AND CONVERT(FLOAT,MY_FIELD) / 2147483647 <= 1
DROP TABLE MY_TABLE
I did it using a Case statement:
Cast(Case When Quantity/[# of Days]= Cast(Quantity/[# of Days] as int) Then abs(Quantity/[# of Days]) Else 0 End as int)
To test whether the input value is an integer or not we can use SQL_VARIANT_PROPERTY function of SQL SERVER.
The following SQL Script will take input and test it whether the data type turns out to be integer or not
declare #convertedTempValue bigint, #inputValue nvarchar(255) = '1' --Change '1' to any input value
set #convertedTempValue = TRY_PARSE(#inputValue as bigint) --we trying to convert to bigint
declare #var3 nvarchar(255) = cast (SQL_VARIANT_PROPERTY(#convertedTempValue,'BaseType') as nvarchar(255)) --we using SQL_VARIANT_PROPERTY to find out datatype
if ( #var3 like '%int%')
begin
print 'value is integer'
end
else
begin
print 'value is non integer'
end
go
Really late to this but would this work?
select * from from table
where (ISNUMERIC(zipcode) = 0 OR zipcode like '%.%')
Filters out items that are integers.
Maybe you should only store integer data in integer datatypes.

Is there a simple way to do hexadecimal arithmetic using sql server/TSQL?

I have a column of hexadecimal values in a table. I want to add a hex value to all values in that table. If it were a simple int I would run something like this:
UPDATE myTable
SET num = num + 4000
Is there any way to do this simply using hexadecimal arithmetic? Or do I have to convert the column value to decimal, convert the value I want to add to decimal, add them, and convert the value back to hex? (And if so, what's the simplest way to do that?)
(NOTE: We are currently using sql server 2000.)
use something like :
print convert(varbinary(4),0 + 0x002E + 0x001D)
it should give you a result like :
0x0000004B
the zero in the equation fools it to believe its all numbers so it calculates the value.
Assuming that num is actually a string representation of the hexadecimal number, I think you can convert it to an integer by using a couple of User Defined Functions:
-- Based on Feodor's solution on
-- http://blog.sqlauthority.com/2010/02/01/sql-server-question-how-to-convert-hex-to-decimal/
CREATE FUNCTION fn_HexToInt(#str varchar(16))
RETURNS BIGINT AS BEGIN
SELECT #str=upper(#str)
DECLARE #i int, #len int, #char char(1), #output bigint
SELECT #len=len(#str),#i=#len, #output=case WHEN #len>0 THEN 0 END
WHILE (#i>0)
BEGIN
SELECT #char=substring(#str,#i,1)
, #output=#output
+(ASCII(#char)
-(case when #char between 'A' and 'F' then 55
else case when #char between '0' and '9' then 48 end
end))
*power(16.,#len-#i)
, #i=#i-1
END
RETURN #output
END
-- Example conversion back to hex string - not very tested
CREATE FUNCTION fn_IntToHex(#num int)
RETURNS VARCHAR(16) AS BEGIN
DECLARE #output varchar(16), #rem int
SELECT #output = '', #rem=0
WHILE (#num > 0)
BEGIN
SELECT #rem = #num % 16
SELECT #num = #num / 16
SELECT #output = char(#rem + case when #rem between 0 and 9 then 48 else 55 end) + #output
END
RETURN #output
END
select dbo.fn_HexToInt ('7FFF') -- = 32767
select dbo.fn_IntToHex(32767) -- = 7FFF
So you can try
UPDATE myTable
SET num = dbo.fn_IntToHex(dbo.fn_HexToInt(num) + 4000)
You can use the prefix 0x
eg
Select 0x3F + 2
returns 65
So
UPDATE myTable
SET num = num + 0x4000
(This works in SQL 2008 - I'm not sure if it's new since SQL 2000 - let me know!)
If you have two 0x values, they get concatenated by the + operator, so use convert to convert one of them to an int

Best equivalent for IsInteger in SQL Server

What is the best way to determine whether or not a field's value is an integer in SQL Server (2000/2005/2008)?
IsNumeric returns true for a variety of formats that would not likely convert to an integer. Examples include '15,000' and '15.1'.
You can use a like statement but that only appears to work well for fields that have a pre-determined number of digits...
select * where zipcode like '[0-9][0-9][0-9][0-9][0-9]'
I could write a user defined function that attempts to convert a varchar parameter to an int within a try/catch block but I'm checking with the community to see if someone has come across any succient methods to achieve this goal - preferably one that can be used within the where clause of a SQL statement without creating other objects.
Late entry that handles negative
ISNUMERIC(zipcode + '.0e0') --integer
ISNUMERIC(zipcode + 'e0') --decimal
For more see this
1 approach is
zipcode NOT LIKE '%[^0-9]%'
Double negatives, got to love 'em!
If SQL Server 2005+, I'd enable CLR and create the function to support regexes. For SQL Server 2000, see this article for creating a UDF to do the same thing.
Then I'd use the regex: ^\d{5}$
This expression gives 1 for an integer value and 0 otherwise
floor((floor(abs(zipcode)))/abs(zipcode))
Why not just use the following? I can't see to find any cases where it fails.
1 = integer
0 = not integer
null = non-numeric
DECLARE #TestValue nvarchar(MAX)
SET #TestValue = '1.04343234e5'
SELECT CASE WHEN ISNUMERIC(#TestValue) = 1
THEN CASE WHEN ROUND(#TestValue,0,1) = #TestValue
THEN 1
ELSE 0
END
ELSE null
END AS Analysis
It looks like this question needs an updated answer.
Limiting the answer to the question title:
where ISNUMERIC(zipcode) = 1
and zipcode - FLOOR(zipcode) = 0
Expounding based on the text of the question...
Currently-supported versions of SQL Server all support/include the TRY-CONVERT function.
declare #a varchar(100)
set #a = '-1.2a'
--set #a = '-1.2'
--set #a = '-1'
--set #a = '-1.0'
--set #a = '-0'
--set #a = '0'
--set #a = '1'
select #a as 'Value'
, ISNUMERIC(#a) as ISNUMERIC
, case when ISNUMERIC(#a) = 1 and #a - FLOOR(#a) = 0 then 1 else 0 end as ISINTEGER
, case when try_convert(int, #a) >= 0 and left(#a, 1) <> '-' then 1 else 0 end as ISWHOLENUMBER
, case when try_convert(int, #a) > 0 then 1 else 0 end as ISCOUNTINGNUMBER
You'll notice that TRY_CONVERT(INT, -1.0) returns NULL. So TRY_CONVERT(INT, #a) IS NOT NULL is not quite right for ISINTEGER.
case when ISNUMERIC(#a) = 1 and #a - FLOOR(#a) = 0 then 1 else 0 end as ISINTEGER
...works because if ISNUMERIC(#a) = 1 is false, FLOOR(#a) is not evaluated. Reversing the order...
case when #a - FLOOR(#a) = 0 and ISNUMERIC(#a) = 1 then 1 else 0 end as ISINTEGER
...generates an error when the value (#a) is not numeric.
So, for the case of zipcode, assuming you want to verify that a 5-digit zip code is a number and it must be 5 digits (so it can't be zero or less) and would never contain a decimal point (so you don't need to know if 12345.000 is an integer):
where try_convert(int, zipcode) > 0
and len(zipcode) = 5
I came up with the perfect answer for this on another StackO question.
It also proves you cannot use ".0e0" like one user suggests here.
It does so without CLR or non-scalar functions.
Please check it out: https://stackoverflow.com/a/10645764/555798
After moving to sql 2008, I was struggling with isnumeric('\8') returning true but throwing an error when casting to an integer. Apparently forward slash is valid currency for yen or won - (reference http://www.louiebao.net/blog/200910/isnumeric/)
My solution was
case when ISNUMERIC(#str) > 0 and not rtrim(#str) LIKE '[^0-9]%' and not rtrim(#str) LIKE '%[^0-9]' and not rtrim(#str) LIKE '[^0-9]%' then rtrim(#str) else null end
See whether the below code will help.
In the below values only 9, 2147483647, 1234567 are eligible as
Integer. We can create this as function and can use this.
CREATE TABLE MY_TABLE(MY_FIELD VARCHAR(50))
INSERT INTO MY_TABLE
VALUES('9.123'),('1234567'),('9'),('2147483647'),('2147483647.01'),('2147483648'), ('2147483648ABCD'),('214,7483,648')
SELECT *
FROM MY_TABLE
WHERE CHARINDEX('.',MY_FIELD) = 0 AND CHARINDEX(',',MY_FIELD) = 0
AND ISNUMERIC(MY_FIELD) = 1 AND CONVERT(FLOAT,MY_FIELD) / 2147483647 <= 1
DROP TABLE MY_TABLE
I did it using a Case statement:
Cast(Case When Quantity/[# of Days]= Cast(Quantity/[# of Days] as int) Then abs(Quantity/[# of Days]) Else 0 End as int)
To test whether the input value is an integer or not we can use SQL_VARIANT_PROPERTY function of SQL SERVER.
The following SQL Script will take input and test it whether the data type turns out to be integer or not
declare #convertedTempValue bigint, #inputValue nvarchar(255) = '1' --Change '1' to any input value
set #convertedTempValue = TRY_PARSE(#inputValue as bigint) --we trying to convert to bigint
declare #var3 nvarchar(255) = cast (SQL_VARIANT_PROPERTY(#convertedTempValue,'BaseType') as nvarchar(255)) --we using SQL_VARIANT_PROPERTY to find out datatype
if ( #var3 like '%int%')
begin
print 'value is integer'
end
else
begin
print 'value is non integer'
end
go
Really late to this but would this work?
select * from from table
where (ISNUMERIC(zipcode) = 0 OR zipcode like '%.%')
Filters out items that are integers.
Maybe you should only store integer data in integer datatypes.