Removing only the leading zero and not all zeros - sql

the goal is to take the numbers in between 2 dashes and I was able to do that but the issue is that I need to remove the leading zero to the returned value. How can I incorporate the LTRIM function or other functions without removing all zeros?
Sample:
123-010-456
Results should be 10
SELECT[Phone],
REPLACE(SUBSTRING([Phone], CHARINDEX('-', [Phone]), CHARINDEX('-', [Phone])),'-','') AS substring
FROM [SalesLT].[Customer]

If your data pattern/format is fixed then below will help
SELECT RIGHT(PARSENAME(REPLACE('123-010-456','-','.'),2),2)

You can combine the following to one query, but for better understanding I break it down to 3 steps.
DECLARE #String nvarchar(20) = '123-010-456'
DECLARE #MiddlePart nvarchar(20)
DECLARE #FirstNonZero int
--Get the middle part
SET #MiddlePart = SUBSTRING(#String,
CHARINDEX('-',#String)+1, --Find the 1st dash
LEN(#String)-CHARINDEX('-',#String)-CHARINDEX('-',Reverse(#String)) --Find length between two dashes
)
--Get the First Non zero number
SET #FirstNonZero = (SELECT MIN(x)
FROM (SELECT CHARINDEX('1',#MiddlePart) as x WHERE CHARINDEX('1',#MiddlePart)>0
UNION
SELECT CHARINDEX('2',#MiddlePart) as x WHERE CHARINDEX('2',#MiddlePart)>0
UNION
SELECT CHARINDEX('3',#MiddlePart) as x WHERE CHARINDEX('3',#MiddlePart)>0
UNION
SELECT CHARINDEX('4',#MiddlePart) as x WHERE CHARINDEX('4',#MiddlePart)>0
UNION
SELECT CHARINDEX('5',#MiddlePart) as x WHERE CHARINDEX('5',#MiddlePart)>0
UNION
SELECT CHARINDEX('6',#MiddlePart) as x WHERE CHARINDEX('6',#MiddlePart)>0
UNION
SELECT CHARINDEX('7',#MiddlePart) as x WHERE CHARINDEX('7',#MiddlePart)>0
UNION
SELECT CHARINDEX('8',#MiddlePart) as x WHERE CHARINDEX('8',#MiddlePart)>0
UNION
SELECT CHARINDEX('9',#MiddlePart) as x WHERE CHARINDEX('9',#MiddlePart)>0
) a)
--Final
Select SUBSTRING(#MiddlePart,#FirstNonZero,LEN(#MiddlePart)-#FirstNonZero+1)

You could try to extract the middle part and convert it to int - this will remove all leading zeroes while keeping the trailing ones... if required, you can then convert it back to varchar. Following an example:
DECLARE #t TABLE(testval nvarchar(40))
INSERT INTO #t VALUES
('123-010-456')
,('1234-1-456789')
,('12-00010-4')
,('1-0007-4')
SELECT *
,SUBSTRING(testval, CHARINDEX('-', testval)+1, CHARINDEX('-', testval, CHARINDEX('-', testval)+1)-CHARINDEX('-', testval)-1)
,CAST(SUBSTRING(testval, CHARINDEX('-', testval)+1, CHARINDEX('-', testval, CHARINDEX('-', testval)+1)-CHARINDEX('-', testval)-1) AS INT)
FROM #t

Related

Parse two Numbers from Text

I want to parse number from Text Line in SQL.
My Text line is as:
I want to retrieve values of First & second as column using SQL as below.
Here's an implementation that you can then use as a procedure on select:
DECLARE #row VARCHAR(MAX);
SET #row = 'First:87.85 Second:87.88 mtr'
DECLARE #result VARCHAR(MAX);
SET #result =
RTRIM(LTRIM(REPLACE(REPLACE(REPLACE(#row,'mtr',''),'First:',''),'Second:','')))
SELECT
SUBSTRING(#result,0,charindex(' ',#result)) As First,
SUBSTRING(#result,charindex(' ',#result),LEN(#result)) AS Second
This treats one row at a time.
Live demo
Assuming the structure of the strings is fixed, one fairly simple way is to use a common table expression with lots of charindex columns to get the start and end positions of the numbers, and then select from that cte with substring.
First, create and populate sample table(Please save us this step in your future questions)
DECLARE #T AS TABLE
(
col varchar(100)
)
INSERT INTO #T (col) VALUES
('First:87.85 Second:87.85 mtr'),
('First:8 Second:82 mtr'),
('First:85 Second:8 mtr'),
('First:7.5 Second:87 mtr');
The cte:
WITH CTE AS
(
SELECT col As String,
7 As FirstStart,
CHARINDEX(' Second', col) As FirstEnd,
CHARINDEX(' Second', col) + 8 As SecondStart,
CHARINDEX(' ', col, CHARINDEX(' Second', col)+1) As SecondEnd
FROM #T
)
The select statement:
SELECT SUBSTRING(String, FirstStart, FirstEnd - FirstStart) As First,
SUBSTRING(String, SecondStart, SecondEnd - SecondStart) As Second
FROM CTE
Results:
First Second
87.85 87.85
8 82
85 8
7.5 87
You can see a live demo on rextester.

I want to remove part of string from a string

Thank you in advance.
I want to remove string after . including ., but length is variable and string can be of any length.
1)Example:
Input:- SCC0204.X and FRK0005.X and RF0023.X and ADF1010.A and HGT9010.V
Output: SCC0204 and FRK0005 and RF0023 and ADF1010.A and HGT9010.V
I tried using the charindex but as the length keeps on changing i wasn't able to do it. I want to trim the values with ending with only X
Any help will be greatly appreciated.
Assuming there is only one dot
UPDATE TABLE
SET column_name = left(column_name, charindex('.', column_name) - 1)
For SELECT
select left(column_name, charindex('.', column_name) - 1) AS col
from your_table
Hope this helps. The code only trims the string when the value has a decimal "." in it and if that value is equal to .X
;WITH cte_TestData(Code) AS
(
SELECT 'SCC0204.X' UNION ALL
SELECT 'FRK0005.X' UNION ALL
SELECT 'RF0023.X' UNION ALL
SELECT 'ADF1010.A' UNION ALL
SELECT 'HGT9010.V' UNION ALL
SELECT 'SCC0204' UNION ALL
SELECT 'FRK0005'
)
SELECT CASE
WHEN CHARINDEX('.', Code) > 0 AND RIGHT(Code,2) = '.X'
THEN SUBSTRING(Code, 1, CHARINDEX('.', Code) - 1)
ELSE Code
END
FROM cte_TestData
If the criteria is only to replace remove .X then probably this should also work
;WITH cte_TestData(Code) AS
(
SELECT 'SCC0204.X' UNION ALL
SELECT 'FRK0005.X' UNION ALL
SELECT 'RF0023.X' UNION ALL
SELECT 'ADF1010.A' UNION ALL
SELECT 'HGT9010.V' UNION ALL
SELECT 'SCC0204' UNION ALL
SELECT 'FRK0005'
)
SELECT REPLACE (Code,'.X','')
FROM cte_TestData
Use LEFT String function :
DECLARE #String VARCHAR(100) = 'SCC0204.XXXXX'
SELECT LEFT(#String,CHARINDEX('.', #String) - 1)
I think your best bet here is to create a function that parses the string and uses regex. I hope this old post helps:
Perform regex (replace) in an SQL query
However, if the value you need to trim is constantly ".X", then you should use
select replace(string, '.x', '')
Please check the below code. I think this will help you.
DECLARE #String VARCHAR(100) = 'SCC0204.X'
IF (SELECT RIGHT(#String,2)) ='.X'
SELECT LEFT(#String,CHARINDEX('.', #String) - 1)
ELSE
SELECT #String
Update: I just missed one of the comments where the OP clarifies the requirement. What I put together below is how you would deal with a requirement to remove everything after the first dot on strings ending with X. I leave this here for reference.
;WITH cte_TestData(Code) AS
(
SELECT 'SCC0204.X' UNION ALL -- ends with '.X'
SELECT 'FRK.000.X' UNION ALL -- ends with '.X', contains multiple dots
SELECT 'RF0023.AX' UNION ALL -- ends with '.AX'
SELECT 'ADF1010.A' UNION ALL -- ends with '.A'
SELECT 'HGT9010.V' UNION ALL -- ends with '.V'
SELECT 'SCC0204.XF' UNION ALL -- ends with '.XF'
SELECT 'FRK0005' UNION ALL -- totally clean
SELECT 'ABCX' -- ends with 'X', not dots
)
SELECT
orig_string = code,
newstring =
SUBSTRING
(
code, 1,
CASE
WHEN code LIKE '%X'
THEN ISNULL(NULLIF(CHARINDEX('.',code)-1, -1), LEN(code))
ELSE LEN(code)
END
)
FROM cte_TestData;
FYI - SQL Server 2012+ you could simplify this code like this:
SELECT
orig_string = code,
newstring =
SUBSTRING(code, 1,IIF(code LIKE '%X', ISNULL(NULLIF(CHARINDEX('.',code)-1, -1), LEN(code)), LEN(code)))
FROM cte_TestData;
With SUBSTRING you can achieve your requirements by below code.
SELECT SUBSTRING(column_name, 0, CHARINDEX('.', column_name)) AS col
FROM your_table
If you want to remove fixed .X from string you can also use REPLACE function.
SELECT REPLACE(column_name, '.X', '') AS col

Get everything before a certain character in SQL

I got the following entries in my database:
E01234-1-1
E01234444-1-800000000
I want to trim the entry so I get:
E01234-1
E01234444-1
So basically, I want everything before the second '-' regardless of the length
How can I solve it? Im using MS SQL SERVER 2012
I am using this but it only bring data from before first hyphen, not second hyphen
DECLARE #TABLE TABLE (STRING VARCHAR(100))
INSERT INTO #TABLE (STRING)
SELECT 'E01234-1-1'
UNION ALL SELECT 'E01234-1-200'
UNION ALL SELECT 'E01234-1-3000'
UNION ALL SELECT 'E01234-1-40000'
UNION ALL SELECT 'E01234-1-500000'
UNION ALL SELECT 'E01234-1-6000000'
UNION ALL SELECT 'E01234-1-70000000'
UNION ALL SELECT 'E01234444-1-800000000'
SELECT LEFT(STRING, CHARINDEX('-',STRING)-1) STRIPPED_STRING from #TABLE
RETURNS
E01234
E01234
E01234
E01234
E01234
E01234
E01234
E01234444
If you need the second -:
SELECT
LEFT(STRING, CHARINDEX('-', #test, CHARINDEX('-', #test) + 1) -1) STRIPPED_STRING
FROM #TABLE
Explanation: CHARINDEX will get you the index of the - - doing it twice (+ 1) specifies that the outter CHARINDEX should start at the spot after the first - in the string.
If you want to chop off everything after the last - instead (regardless of whether it's second or not):
SELECT
LEFT(STRING, LEN(STRING) - CHARINDEX('-', REVERSE(STRING))) STRIPPED_STRING
FROM #table
This time, you get the CHARINDEX of the last (reverse the string) -, and subtract that from the length of the whole string.
Try this:
DECLARE #STR NVARCHAR(MAX) = 'E01234444-1-800000000';
SELECT LEFT(#STR, CHARINDEX('-', #STR, CHARINDEX('-', #STR)) - 1)
If you are using MySQL use something like this:
SELECT SUBSTRING_INDEX(fieldname, '-', 2) FROM tablename

Formatting a number as a monetary value including separators

I need some help with a sql transformation. This part of query that I have been provided with:
'$' + replace(cast((CAST(p.Price1 AS decimal(10,2)) * cast(isnull(p.Multiplier,1) as decimal(10,2))) as varchar), '.0000', '')
Basically, it ends up being a varchar that looks like this: $26980
I need to insert a comma at the thousand and million mark (if applicable). So in this instance, $26,980
What's the easiest way to do that without having to rewrite the whole thing?
Do it on the client side. Having said that, this example should show you the way.
with p(price1, multiplier) as (select 1234.5, 10)
select '$' + replace(cast((CAST(p.Price1 AS decimal(10,2)) * cast(isnull(p.Multiplier,1) as decimal(10,2))) as varchar), '.0000', ''),
'$' + parsename(convert(varchar,cast(p.price1*isnull(p.Multiplier,1) as money),1),2)
from p
The key is in the last expression
'$' + parsename(convert(varchar,cast(p.price1*isnull(p.Multiplier,1) as money),1),2)
Note: if p.price1 is of a higher precision than decimal(10,2), then you may have to cast it in the expression as well to produce a faithful translation since the original CAST(p.Priced1 as decimal(10,2)) will be performing rounding.
If you really must do it in TSQL you can use CONVERT(), but this sort of thing really doesn't belong in the database:
declare #m money = 12345678
-- with decimal places
select '$' + convert(varchar, #m, 1)
-- without decimal places
select '$' + replace(convert(varchar, #m, 1), '.00', '')
You could turn this into a function, it only goes 50 characters back.
DECLARE #input VARCHAR(50)
SELECT #input = '123123123.00'
SELECT #input = CASE WHEN CHARINDEX('.', #input) > offset +1
THEN STUFF(#input, CHARINDEX('.', #input) - offset, 0, ',')
ELSE #input END
FROM (SELECT 3 offset UNION SELECT 7 UNION SELECT 12 UNION SELECT 18 UNION SELECT 25 UNION SELECT 33 UNION SELECT 42) b
PRINT #input
The offset grows by +1 for each position, because it's assuming you've already inserted the commas for the previous positions.

Strip non-numeric characters from a string

I'm currently doing a data conversion project and need to strip all alphabetical characters from a string. Unfortunately I can't create or use a function as we don't own the source machine making the methods I've found from searching for previous posts unusable.
What would be the best way to do this in a select statement? Speed isn't too much of an issue as this will only be running over 30,000 records or so and is a once off statement.
You can do this in a single statement. You're not really creating a statement with 200+ REPLACEs are you?!
update tbl
set S = U.clean
from tbl
cross apply
(
select Substring(tbl.S,v.number,1)
-- this table will cater for strings up to length 2047
from master..spt_values v
where v.type='P' and v.number between 1 and len(tbl.S)
and Substring(tbl.S,v.number,1) like '[0-9]'
order by v.number
for xml path ('')
) U(clean)
Working SQL Fiddle showing this query with sample data
Replicated below for posterity:
create table tbl (ID int identity, S varchar(500))
insert tbl select 'asdlfj;390312hr9fasd9uhf012 3or h239ur ' + char(13) + 'asdfasf'
insert tbl select '123'
insert tbl select ''
insert tbl select null
insert tbl select '123 a 124'
Results
ID S
1 390312990123239
2 123
3 (null)
4 (null)
5 123124
CTE comes for HELP here.
;WITH CTE AS
(
SELECT
[ProductNumber] AS OrigProductNumber
,CAST([ProductNumber] AS VARCHAR(100)) AS [ProductNumber]
FROM [AdventureWorks].[Production].[Product]
UNION ALL
SELECT OrigProductNumber
,CAST(STUFF([ProductNumber], PATINDEX('%[^0-9]%', [ProductNumber]), 1, '') AS VARCHAR(100) ) AS [ProductNumber]
FROM CTE WHERE PATINDEX('%[^0-9]%', [ProductNumber]) > 0
)
SELECT * FROM CTE
WHERE PATINDEX('%[^0-9]%', [ProductNumber]) = 0
OPTION (MAXRECURSION 0)
output:
OrigProductNumber ProductNumber
WB-H098 098
VE-C304-S 304
VE-C304-M 304
VE-C304-L 304
TT-T092 092
RichardTheKiwi's script in a function for use in selects without cross apply,
also added dot because in my case I use it for double and money values within a varchar field
CREATE FUNCTION dbo.ReplaceNonNumericChars (#string VARCHAR(5000))
RETURNS VARCHAR(1000)
AS
BEGIN
SET #string = REPLACE(#string, ',', '.')
SET #string = (SELECT SUBSTRING(#string, v.number, 1)
FROM master..spt_values v
WHERE v.type = 'P'
AND v.number BETWEEN 1 AND LEN(#string)
AND (SUBSTRING(#string, v.number, 1) LIKE '[0-9]'
OR SUBSTRING(#string, v.number, 1) LIKE '[.]')
ORDER BY v.number
FOR
XML PATH('')
)
RETURN #string
END
GO
Thanks RichardTheKiwi +1
Well if you really can't use a function, I suppose you could do something like this:
SELECT REPLACE(REPLACE(REPLACE(LOWER(col),'a',''),'b',''),'c','')
FROM dbo.table...
Obviously it would be a lot uglier than that, since I only handled the first three letters, but it should give the idea.