SQL Trim Preceding zeros - sql

I have an ID that looks like below:
000000000000000091
000000000000000019
000000000000001859
000000000000001220
000000000000001220
000000000000001182
000000000000010156
I am looking to trim the preceeding zero's so only yhe
I need to trim the values so it shows up like below:
91
19
1859
1220
1220
1182
10156
I am trying to do the following:
UPDATE TABLE_NAME SET Material = RTRIM(LTRIM(REPLACE(Material,'0',' '))),' ','0'

You can use Substring with PatIndex without any conversion.
UPDATE TABLE_NAME SET Material = Substring(Material, PatIndex('%[1-9]%',Material),Len(Material))

If the numbers are integers below the 2^63 mark you can use CAST(). For example:
with
t as (
select '000000000000000091' as v
union all select '000000000000000019'
union all select '000000000000001859'
union all select '000000000000001220'
union all select '000000000000001220'
union all select '000000000000001182'
union all select '000000000000010156'
)
select '' + cast(v as bigint) from t
Result:
(No column name)
----------------
91
19
1859
1220
1220
1182
10156
See running example at db<>fiddle.

Can you try casting it to int or bigint?
Something like
UPDATE TABLE_NAME SET Material = CAST(Material AS BIGINT)
For your input
WITH DATA AS
(
SELECT Material
FROM
(
VALUES('000000000000000091'),
('000000000000000019'),
('000000000000001859'),
('000000000000001220'),
('000000000000001220'),
('000000000000001182'),
('000000000000010156')
) Data (Material)
)
SELECT Material, CAST(Material AS BIGINT) AS Material_Output
FROM Data

Related

How to replace a string value with single character

I want to mask the data except the last four characters.
For example:
If there is a varchar column (Name) with the value Rio De janerio, I want to mask it as xxx xx xxxerio.
If it is a numeric column (acc number) with value 123 453 6987,then I want it to be displayed as 000 000 6987.
I tried using right and replace function. But I could not find the solution.
Mask the data except last four characters/numbers
On Oracle, You can try below query to replace numbers with 0s -
SELECT REGEXP_REPLACE (SUBSTR('123 453 6987', 1, LENGTH('123 453 6987')-4), '\d', '0') || SUBSTR('123 453 6987', -4, 4) PROCESSED_STRING
FROM DUAL;
PROCESSED_STRING
000 000 6987
For Replacing strings with #s -
SELECT REGEXP_REPLACE (SUBSTR('Rio De janerio', 1, LENGTH('Rio De janerio')-4), '\S', '#') || SUBSTR('Rio De janerio', -4, 4) PROCESSED_STRING
FROM DUAL;
PROCESSED_STRING
### ## ###erio
Here is the fiddle.
This is not a complete solution but it is just a idea and a head up to move you in the right direction . You can modify the query as per your requirement .
In SQL SERVER :
create table place
(
place_name varchar(100),
place_pincode varchar(100)
)
insert into place values ('Rio De janerio',1234536987)
select substring(place_pincode,len(place_pincode)-3,len(place_pincode)),
case when isnumeric(place_pincode)=1 then
concat('000000',substring(place_pincode,len(place_pincode)-3,len(place_pincode))) end as place_pincode,
case when isnumeric(place_name)<>1 then
concat('XXXXXX',substring(place_name,len(place_name)-3,len(place_name))) end as place_name
from place
If you are using SQL Server 2016 and above you can use Translate function:
declare #name varchar(50) = 'Rio De janerio'
select translate(substring(#name,1,len(#name)-4),'abcdefghijklmnopqrstuvwxyz','**************************') + right(#name,4)
declare #i int = 1234536987
select translate(substring(convert(varchar(50),#i),1,len(#i)-4),'0123456789','0000000000') + right(#i,4)
Using SQLSERVER STUFF() and PATINDEX() will solve this question
FOR MASKING THE NAME
declare #str varchar(20)
declare #rcInt int
set #str ='Rio De janerio'
set #rcInt = 4;
with cte as
(select left(#str, len(#str)-#rcInt) as name
),
rn as
(select stuff(name, patindex('%[a-z]%',name), 1, 'X') as ch, patindex('%[a-z]%',name)as rn, name from cte
union all
select stuff(ch, rn+patindex('%[a-z]%',substring(name, rn+1, len(name))), 1, 'X') as ch, rn+patindex('%[a-z]%',substring(name, rn+1, len(name)))as rn, name from rn
where patindex('%[a-z]%',substring(name, rn+1, len(name)))>0
)
select top 1 ch + right(#str, #rcInt) from rn order by rn desc
FOR TELEPHONE NUMBER (as function)
create function ufn_MaskPhoneNum(
#str varchar(20),
#rcInt int
)
returns #tblReturn table(maskedStr varchar(100))
as
begin
with cte as
(select left(#str, len(#str)-#rcInt) as name
),
rn as
(select stuff(name, patindex('%[0-9]%',name), 1, 'X') as ch, patindex('%[0-9]%',name)as rn, name from cte
union all
select stuff(ch, rn+patindex('%[0-9]%',substring(name, rn+1, len(name))), 1, 'X') as ch,
rn+patindex('%[0-9]%',substring(name, rn+1, len(name)))as rn, name from rn
where patindex('%[0-9]%',substring(name, rn+1, len(name)))>0
)
insert into #tblReturn
select top 1 ch + right(#str, #rcInt) from rn order by rn desc
return;
end
sample:
select * from ufn_MaskPhoneNum('123 453 6987', 4)

substract specific string from data sql

I am new to SQL
If I have a column like this
ID
00001234
00012345
00001235
00123456
I want to see a column of ID without '0' Like this
ID
1234
12345
1235
123456
How can I start? any advice?
In SQL Server you can use:
SELECT ID,
REPLACE(LTRIM(REPLACE(ID, '0', ' ') ), ' ', '0')
FROM mytable
The above can be easily adjusted to any other RDBMS you may use.
Cast it to Bigint and cast it back to varchar
Note:Assumption: RDBMS SQL SERVER, ID is of character type
SELECT * INTO #TAB FROM (
select '00001234' ID
UNION ALL
select '00012345'
UNION ALL
select '00001235'
UNION ALL
select '00123456'
)A
SELECT CAST(CAST(ID AS BIGINT) AS VARCHAR(50)) FROM #TAB

Computed column does not include one of the values

I'm trying to create a computed column in order to have a unique index on a nullable column that ignores NULL rows1. I've composed this test case:
SELECT TEST_ID, CODE, UNIQUE_CODE, CAST(UNIQUE_CODE AS VARBINARY(4000)) AS HEX
FROM (
SELECT TEST_ID, CODE,
ISNULL(CODE, CONVERT(VARCHAR, SPACE(10)) + CONVERT(VARCHAR, TEST_ID)) AS UNIQUE_CODE
FROM (
SELECT 1 AS TEST_ID, 'ABCDEFGHIJ' AS CODE
UNION ALL
SELECT 2, 'XYZ'
UNION ALL
SELECT 3, NULL
) TEST
) X;
It works as expected when CODE is not null but I only get a string of whitespaces when CODE is null (i.e., the trailing TEST_ID is missing):
TEST_ID | CODE | UNIQUE_CODE | HEX
--------+------------+-------------+-----------------------
1 | ABCDEFGHIJ | ABCDEFGHIJ | 0x4142434445464748494A
2 | XYZ | XYZ | 0x58595A
3 | NULL | | 0x20202020202020202020
The funny thing is that I already use this technique successfully in another table and I can't spot the difference:
CREATE TABLE SOME_OTHER_TABLE (
SOME_OTHER_TABLE_ID INT IDENTITY(1, 1) NOT NULL,
NOMBRE VARCHAR(50),
-- This works just fine:
NOMBRE_UNICO AS ISNULL(NOMBRE, CONVERT(VARCHAR, SPACE(50)) + CONVERT(VARCHAR, SOME_OTHER_TABLE_ID)),
CONSTRAINT SOME_OTHER_TABLE_PK PRIMARY KEY (SOME_OTHER_TABLE_ID)
);
What am I missing?
(1) This was a workaround for SQL Server 2005 that's no longer necessary in later versions thanks to filtered indexes.
There you go with " 3"
SELECT TEST_ID, CODE, UNIQUE_CODE, CAST(UNIQUE_CODE AS VARBINARY(4000)) AS HEX
FROM (
SELECT TEST_ID, CODE,
ISNULL(CODE, CONVERT(VARCHAR(20), SPACE(10)) + CONVERT(VARCHAR(20), TEST_ID)) AS UNIQUE_CODE
FROM (
SELECT 1 AS TEST_ID, cast('ABCDEFGHIJ' as varchar(20)) AS CODE
UNION ALL
SELECT 2, 'XYZ'
UNION ALL
SELECT 3, NULL
) TEST
) X;
'ABCDEFGHIJ' (first value in the union list) is exactly 10 characters and this column is a first argument of IsNull. So it takes 10 characters as size for IsNull result. Which is enough only for spaces. Replacing this constant with 'ABCDEFGHIJKLMNOPQR' would do the trick also.
It looks like SQL is trying to help out to define the column length in your inner query. By casting/converting to a specific size this fixes the problem. Once your UNIQUE_CODE field exceeds this value, the returned value is limited to the size of the column.
SELECT TEST_ID, CODE, UNIQUE_CODE, CAST(UNIQUE_CODE AS VARBINARY(4000)) AS HEX
FROM (
SELECT TEST_ID, CODE,
ISNULL(CODE, CONVERT(VARCHAR, SPACE(10)) + CONVERT(VARCHAR, TEST_ID)) AS UNIQUE_CODE
FROM (
SELECT 1 AS TEST_ID, CONVERT(VARCHAR(50), 'ABCDEFGHIJ') AS CODE
UNION ALL
SELECT 2, 'XYZ'
UNION ALL
SELECT 3, NULL
) TEST
) X;
You can run below piece of code to find out why ?
this fails :
declare #a char(20)
set #a=null
declare #b char(10)
set #b='aaaaaa'
select isnull(#a,convert(char(10),space(10)+#b))
This works:
declare #a char(20)
set #a=null
declare #b char(10)
set #b='aaaaaa'
select isnull(#a,convert(char(30),space(10)+#b))

SQL Select values starting with a capital letter

I have a table with a varchar type column. I want to select values from this column which start with a capital letter only.
For example
MyTable
Col1 Col2
Argentina 2
Brasil 3
uruguay 4
I want my select query to return:
Argentina
Brasil
This is a bit of a pain. You can use ASCII() or COLLATE, but these depend on how the data is stored. For varchar() and char(), this will work:
where ASCII(left(col1, 1)) between ASCII('A') and ASCII('Z')
With TestData As
(
Select '012324' As Name
Union All Select 'ABC'
Union All Select 'abc'
Union All Select 'aBc'
Union All Select 'ABé'
Union All Select 'ABÉ'
)
Select *
From TestData
Where Name = UPPER(Name) Collate SQL_Latin1_General_CP1_CS_AS
hope this will help
You Can Use UPPER AND COLLATE Functions to do this.
For E.g:
create table #a (text varchar(10))
insert into #a values ('HAI'),('Hai'),('hai'),('44A')
select *from #a where substring([text],1,1) = substring(Upper([text]),1,1) collate SQL_Latin1_General_CP1_CS_AS
AND substring([text],1,1) like '[A-Z]%'
select Col1 from MyTable where Col1 like '[A-Z]%'

how to convert string format

How can I convert a number to a formatted string of fixed length in SQL Server 2005 using T-SQL?
e.g.
Inputs: 5,01,007,0009,00011,01200
Result: 000005,000007,000009,0000011,001200
Looks like you want it 6 wide. Try putting your pad characters, in this case, zeros, to the left of your int/string, and then take the 6 chars on the right side of the string.
How about this?
DECLARE #i int;
SELECT #i = 1200;
SELECT RIGHT('000000'+ CAST(#i as varchar(10)), 6);
The best way I've found to do this is using the STR statement:
SELECT REPLACE(STR(123, 6), ' ', '0')
The above statement will result in 000123. It basically converts 123 to a string of 6 characters (padded with spaces), then uses REPLACE to replace the spaces with zeros.
TRY THIS
WITH t(c) AS
(
SELECT 1.99 UNION ALL
SELECT 21.34 UNION ALL
SELECT 1797.94 UNION ALL
SELECT 300.36 UNION ALL
SELECT 21.99 UNION ALL
SELECT -2.31
)
select
c,
replicate(0,4-len(replace(substring(cast(c as varchar(10)),1,charindex('.',c)-1),'-','')))+''+
replace(replace(substring(cast(c as varchar(10)),1,charindex('.',c)-1),'-',''),'','-') +''+
replace(substring(cast(c as varchar(10)),charindex('.',c),len(c)),'-','')
from t
i will still optimize it
Best way for dynamic leading zero allocation
WITH t(c) AS ( SELECT 1.99 UNION ALL
SELECT 21.34 UNION ALL SELECT
1797.94 UNION ALL SELECT 300.36 UNION ALL SELECT 21.99 UNION ALL
SELECT 2.31 ),
Final (a,b,c,d) as ( Select c,
substring(cast(c as
varchar(10)),1,charindex('.',c)-1) ,
(select max(len(substring(cast(c as
varchar(10)),1,charindex('.',c)-1)))
from t), substring(cast(c as
varchar(10)),charindex('.',c)+1,len(c))
From t group by c )
select a,
right(replicate('0',c)+''+b,4)+'.'+d
from final
declare #i int
set #i=10
print replace(str(#i),' ','0')