How to count instances of character in SQL Column - sql

I have an sql column that is a string of 100 'Y' or 'N' characters. For example:
YYNYNYYNNNYYNY...
What is the easiest way to get the count of all 'Y' symbols in each row.

This snippet works in the specific situation where you have a boolean: it answers "how many non-Ns are there?".
SELECT LEN(REPLACE(col, 'N', ''))
If, in a different situation, you were actually trying to count the occurrences of a certain character (for example 'Y') in any given string, use this:
SELECT LEN(col) - LEN(REPLACE(col, 'Y', ''))

In SQL Server:
SELECT LEN(REPLACE(myColumn, 'N', ''))
FROM ...

This gave me accurate results every time...
This is in my Stripes field...
Yellow, Yellow, Yellow, Yellow, Yellow, Yellow, Black, Yellow, Yellow, Red, Yellow, Yellow, Yellow, Black
11 Yellows
2 Black
1 Red
SELECT (LEN(Stripes) - LEN(REPLACE(Stripes, 'Red', ''))) / LEN('Red')
FROM t_Contacts

DECLARE #StringToFind VARCHAR(100) = "Text To Count"
SELECT (LEN([Field To Search]) - LEN(REPLACE([Field To Search],#StringToFind,'')))/COALESCE(NULLIF(LEN(#StringToFind), 0), 1) --protect division from zero
FROM [Table To Search]

This will return number of occurance of N
select ColumnName, LEN(ColumnName)- LEN(REPLACE(ColumnName, 'N', ''))
from Table

The easiest way is by using Oracle function:
SELECT REGEXP_COUNT(COLUMN_NAME,'CONDITION') FROM TABLE_NAME

Maybe something like this...
SELECT
LEN(REPLACE(ColumnName, 'N', '')) as NumberOfYs
FROM
SomeTable

Below solution help to find out no of character present from a string with a limitation:
1) using SELECT LEN(REPLACE(myColumn, 'N', '')), but limitation and
wrong output in below condition:
SELECT LEN(REPLACE('YYNYNYYNNNYYNY', 'N', ''));
--8 --Correct
SELECT LEN(REPLACE('123a123a12', 'a', ''));
--8 --Wrong
SELECT LEN(REPLACE('123a123a12', '1', ''));
--7 --Wrong
2) Try with below solution for correct output:
Create a function and also modify as per requirement.
And call function as per below
select dbo.vj_count_char_from_string('123a123a12','2');
--2 --Correct
select dbo.vj_count_char_from_string('123a123a12','a');
--2 --Correct
-- ================================================
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: VIKRAM JAIN
-- Create date: 20 MARCH 2019
-- Description: Count char from string
-- =============================================
create FUNCTION vj_count_char_from_string
(
#string nvarchar(500),
#find_char char(1)
)
RETURNS integer
AS
BEGIN
-- Declare the return variable here
DECLARE #total_char int; DECLARE #position INT;
SET #total_char=0; set #position = 1;
-- Add the T-SQL statements to compute the return value here
if LEN(#string)>0
BEGIN
WHILE #position <= LEN(#string) -1
BEGIN
if SUBSTRING(#string, #position, 1) = #find_char
BEGIN
SET #total_char+= 1;
END
SET #position+= 1;
END
END;
-- Return the result of the function
RETURN #total_char;
END
GO

try this
declare #v varchar(250) = 'test.a,1 ;hheuw-20;'
-- LF ;
select len(replace(#v,';','11'))-len(#v)

If you want to count the number of instances of strings with more than a single character, you can either use the previous solution with regex, or this solution uses STRING_SPLIT, which I believe was introduced in SQL Server 2016. Also you’ll need compatibility level 130 and higher.
ALTER DATABASE [database_name] SET COMPATIBILITY_LEVEL = 130
.
--some data
DECLARE #table TABLE (col varchar(500))
INSERT INTO #table SELECT 'whaCHAR(10)teverCHAR(10)whateverCHAR(10)'
INSERT INTO #table SELECT 'whaCHAR(10)teverwhateverCHAR(10)'
INSERT INTO #table SELECT 'whaCHAR(10)teverCHAR(10)whateverCHAR(10)~'
--string to find
DECLARE #string varchar(100) = 'CHAR(10)'
--select
SELECT
col
, (SELECT COUNT(*) - 1 FROM STRING_SPLIT (REPLACE(REPLACE(col, '~', ''), 'CHAR(10)', '~'), '~')) AS 'NumberOfBreaks'
FROM #table

The second answer provided by nickf is very clever. However, it only works for a character length of the target sub-string of 1 and ignores spaces. Specifically, there were two leading spaces in my data, which SQL helpfully removes (I didn't know this) when all the characters on the right-hand-side are removed. Which meant that
" John Smith"
generated 12 using Nickf's method, whereas:
" Joe Bloggs, John Smith"
generated 10, and
" Joe Bloggs, John Smith, John Smith"
Generated 20.
I've therefore modified the solution slightly to the following, which works for me:
Select (len(replace(Sales_Reps,' ',''))- len(replace((replace(Sales_Reps, ' ','')),'JohnSmith','')))/9 as Count_JS
I'm sure someone can think of a better way of doing it!

You can also Try This
-- DECLARE field because your table type may be text
DECLARE #mmRxClaim nvarchar(MAX)
-- Getting Value from table
SELECT top (1) #mmRxClaim = mRxClaim FROM RxClaim WHERE rxclaimid_PK =362
-- Main String Value
SELECT #mmRxClaim AS MainStringValue
-- Count Multiple Character for this number of space will be number of character
SELECT LEN(#mmRxClaim) - LEN(REPLACE(#mmRxClaim, 'GS', ' ')) AS CountMultipleCharacter
-- Count Single Character for this number of space will be one
SELECT LEN(#mmRxClaim) - LEN(REPLACE(#mmRxClaim, 'G', '')) AS CountSingleCharacter
Output:

If you need to count the char in a string with more then 2 kinds of chars, you can use instead of 'n' - some operator or regex of the chars accept the char you need.
SELECT LEN(REPLACE(col, 'N', ''))

Try this:
SELECT COUNT(DECODE(SUBSTR(UPPER(:main_string),rownum,LENGTH(:search_char)),UPPER(:search_char),1)) search_char_count
FROM DUAL
connect by rownum <= length(:main_string);
It determines the number of single character occurrences as well as the sub-string occurrences in main string.

Here's what I used in Oracle SQL to see if someone was passing a correctly formatted phone number:
WHERE REPLACE(TRANSLATE('555-555-1212','0123456789-','00000000000'),'0','') IS NULL AND
LENGTH(REPLACE(TRANSLATE('555-555-1212','0123456789','0000000000'),'0','')) = 2
The first part checks to see if the phone number has only numbers and the hyphen and the second part checks to see that the phone number has only two hyphens.

for example to calculate the count instances of character (a) in SQL Column ->name is column name
'' ( and in doblequote's is empty i am replace a with nocharecter #'')
select len(name)- len(replace(name,'a','')) from TESTING
select len('YYNYNYYNNNYYNY')- len(replace('YYNYNYYNNNYYNY','y',''))

DECLARE #char NVARCHAR(50);
DECLARE #counter INT = 0;
DECLARE #i INT = 1;
DECLARE #search NVARCHAR(10) = 'Y'
SET #char = N'YYNYNYYNNNYYNY';
WHILE #i <= LEN(#char)
BEGIN
IF SUBSTRING(#char, #i, 1) = #search
SET #counter += 1;
SET #i += 1;
END;
SELECT #counter;

Related

SQL Server 2012 string functions

I have a field that can vary in length of the format CxxRyyy where x and y are numeric. I want to choose xx and yyy. For instance, if the field value is C1R12, then I want to get 1 and 12. if I use substring and charindex then I have to use a length, but I would like to use a position like
SUBSTRING(WPLocationNew, CHARINDEX('C',WPLocationNew,1)+1, CHARINDEX('R',WPLocationNew,1)-1)
or
SUBSTRING(WPLocationNew, CHARINDEX('C',WPLocationNew,1)+1, LEN(WPLocationNew) - CHARINDEX('R',WPLocationNew,1))
to get x, but I know that doesn't work. I feel like there is a fairly simple solution, but I am not coming up with it yet. Any suggestions
If these are cell references and will always be in the form C{1-5 digits}R{1-5 digits} you can do this:
DECLARE #t TABLE(Original varchar(32));
INSERT #t(Original) VALUES ('C14R4535'),('C1R12'),('C57R123');
;WITH src AS
(
SELECT Original, c = REPLACE(REPLACE(Original,'C',''),'R','.')
FROM #t
)
SELECT Original, C = PARSENAME(c,2), R = PARSENAME(c,1)
FROM src;
Output
Original
C
R
C14R4535
14
4535
C1R12
1
12
C57R123
57
123
Example db<>fiddle
If you need to protect against other formats, you can add
FROM #t WHERE Original LIKE 'C%[0-9]%R%[0-9]%'
AND PATINDEX('%[^C^R^0-9]%', Original) = 0
Updated db<>fiddle
It appears that you are attempting to parse an Excel cell reference. Those are predictably structured or I wouldn't suggest such an embarrassing hack as this.
Basically, take advantage of the fact that a try_cast in SQL ignores spaces when converting strings to numbers.
declare #val as varchar(20) = 'C1R12'
declare #newval as varchar(20)
declare #c as smallint
declare #r as smallint
--replace the C with 5 spaces
set #newval = replace(#val,'C',' ')
--replace the R with 5 spaces
set #newval = replace(#newval,'R',' ')
--take a look at the intermediate result, which is ' 1 14'
select #newval
set #c = try_cast(left(#newval,11) as smallint)
set #r = try_cast(right(#newval,6) as smallint)
--take a look at the results... two smallint, 1 and 14
select #c, #r
That can all be accomplished in one line for each element (a line for column and a line for row) but I wanted you to be able to understand what was happening so this example goes through the steps individually.
Here's yet another way:
declare #val as varchar(20) = 'C12R345'
declare #c as varchar(5)
declare #r as varchar(5)
set #c = SUBSTRING(#val, patindex('C%', #val)+1,(patindex('%R%', #val)-1)-patindex('C%', #val) )
set #r = SUBSTRING(#val, patindex('%R%', #val)+1, LEN(#val) -patindex('%R%', #val))
select cast(#c as int) as 'C', cast(#r as int) as 'R'
dbfiddle
There are lots of different ways to approach string parsing. Here's just one possible idea:
declare #s varchar(10) = 'C01R002';
select
rtrim( left(replace(stuff(#s, 1, 1, ''), 'R', ' '), 10)) as c,
ltrim(right(replace(substring(#s, 2, 10), 'R', ' '), 10)) as r
Strip out the 'C' and then replace the 'R' with enough spaces so that the left and right sides can be extracted using a fixed length and then easily trimmed back.
stuff() and substring() as used above are just different ways accomplish exactly the same thing. One advantage here is that it does use fairly portable string functions and it's conceivable that this is somewhat faster. This is also done inline and without multiple steps.

How to identify and redact all instances of a matching pattern in T-SQL

I have a requirement to run a function over certain fields to identify and redact any numbers which are 5 digits or longer, ensuring all but the last 4 digits are replaced with *
For example: "Some text with 12345 and 1234 and 12345678" would become "Some text with *2345 and 1234 and ****5678"
I've used PATINDEX to identify the the starting character of the pattern:
PATINDEX('%[0-9][0-9][0-9][0-9][0-9]%', TEST_TEXT)
I can recursively call that to get the starting character of all the occurrences, but I'm struggling with the actual redaction.
Does anyone have any pointers on how this can be done? I know to use REPLACE to insert the *s where they need to be, it's just the identification of what I should actually be replacing I'm struggling with.
Could do it on a program, but I need it to be T-SQL (can be a function if needed).
Any tips greatly appreciated!
You can do this using the built in functions of SQL Server. All of which used in this example are present in SQL Server 2008 and higher.
DECLARE #String VARCHAR(500) = 'Example Input: 1234567890, 1234, 12345, 123456, 1234567, 123asd456'
DECLARE #StartPos INT = 1, #EndPos INT = 1;
DECLARE #Input VARCHAR(500) = ISNULL(#String, '') + ' '; --Sets input field and adds a control character at the end to make the loop easier.
DECLARE #OutputString VARCHAR(500) = ''; --Initalize an empty string to avoid string null errors
WHILE (#StartPOS <> 0)
BEGIN
SET #StartPOS = PATINDEX('%[0-9][0-9][0-9][0-9][0-9]%', #Input);
IF #StartPOS <> 0
BEGIN
SET #OutputString += SUBSTRING(#Input, 1, #StartPOS - 1); --Seperate all contents before the first occurance of our filter
SET #Input = SUBSTRING(#Input, #StartPOS, 500); --Cut the entire string to the end. Last value must be greater than the original string length to simply cut it all.
SET #EndPos = (PATINDEX('%[0-9][0-9][0-9][0-9][^0-9]%', #Input)); --First occurance of 4 numbers with a not number behind it.
SET #Input = STUFF(#Input, 1, (#EndPos - 1), REPLICATE('*', (#EndPos - 1))); --#EndPos - 1 gives us the amount of chars we want to replace.
END
END
SET #OutputString += #Input; --Append the last element
SET #OutputString = LEFT(#OutputString, LEN(#OutputString))
SELECT #OutputString;
Which outputs the following:
Example Input: ******7890, 1234, *2345, **3456, ***4567, 123asd456
This entire code could also be made as a function since it only requires an input text.
A dirty solution with recursive CTE
DECLARE
#tags nvarchar(max) = N'Some text with 12345 and 1234 and 12345678',
#c nchar(1) = N' ';
;
WITH Process (s, i)
as
(
SELECT #tags, PATINDEX('%[0-9][0-9][0-9][0-9][0-9]%', #tags)
UNION ALL
SELECT value, PATINDEX('%[0-9][0-9][0-9][0-9][0-9]%', value)
FROM
(SELECT SUBSTRING(s,0,i)+'*'+SUBSTRING(s,i+4,len(s)) value
FROM Process
WHERE i >0) calc
-- we surround the value and the string with leading/trailing ,
-- so that cloth isn't a false positive for clothing
)
SELECT * FROM Process
WHERE i=0
I think a better solution it's to add clr function in Ms SQL Server to manage regexp.
sql-clr/RegEx
Here is an option using the DelimitedSplit8K_LEAD which can be found here. https://www.sqlservercentral.com/articles/reaping-the-benefits-of-the-window-functions-in-t-sql-2 This is an extension of Jeff Moden's splitter that is even a little bit faster than the original. The big advantage this splitter has over most of the others is that it returns the ordinal position of each element. One caveat to this is that I am using a space to split on based on your sample data. If you had numbers crammed in the middle of other characters this will ignore them. That may be good or bad depending on you specific requirements.
declare #Something varchar(100) = 'Some text with 12345 and 1234 and 12345678';
with MyCTE as
(
select x.ItemNumber
, Result = isnull(case when TRY_CONVERT(bigint, x.Item) is not null then isnull(replicate('*', len(convert(varchar(20), TRY_CONVERT(bigint, x.Item))) - 4), '') + right(convert(varchar(20), TRY_CONVERT(bigint, x.Item)), 4) end, x.Item)
from dbo.DelimitedSplit8K_LEAD(#Something, ' ') x
)
select Output = stuff((select ' ' + Result
from MyCTE
order by ItemNumber
FOR XML PATH('')), 1, 1, '')
This produces: Some text with *2345 and 1234 and ****5678

in SQL how can I remove the first 3 characters on the left and everything on the right after an specific character

In SQL how can I remove (from displaying on my report no deleting from database) the first 3 characters (CN=) and everything after the comma that is followed by "OU" so that I am left with the name and last name in the same column? for example:
CN=Tom Chess,OU=records,DC=1234564786_data for testing, 1234567
CN=Jack Bauer,OU=records,DC=1234564786_data for testing, 1234567
CN=John Snow,OU=records,DC=1234564786_data for testing, 1234567
CN=Anna Rodriguez,OU=records,DC=1234564786_data for testing, 1234567
Desired display:
Tom Chess
Jack Bauer
John Snow
Anna Rodriguez
I tried playing with TRIM but I don't know how to do it without declaring the position and with names and last names having different lengths I really don't know how to handle that.
Thank you in advance
Update: I wonder about an approach of using Locate to match the position of the comma and then feed that to a sub-string. Not sure if a approach like would work and not sure how to put the syntax together. What do you think? will it be a feasible approach?
You can try this one SUBSTRING(ColumnName, 4, CHARINDEX(',', ColumnName) - 4)
In Postgres, you could use split_part() assuming no name contains a ,
select substr(split_part(the_column, ',', 1), 4)
from ...
Db2 11.x for LUW:
with tab (str) as (values
' CN = Tom Chess , OU = records,DC=1234564786_data for testing, 1234567'
, 'CN=Jack Bauer,OU=records,DC=1234564786_data for testing, 1234567'
, 'CN=John Snow,OU=records,DC=1234564786_data for testing, 1234567'
, 'CN=Anna Rodriguez,OU=records,DC=1234564786_data for testing, 1234567'
)
select REGEXP_REPLACE(str, '^\s*CN\s*=\s*(.*)\s*,\s*OU\s*=.*', '\1')
from tab;
Note, that such a regex pattern allows an arbitrary number of spaces as in the 1-st record of example above.
In Oracle 11g, it might work.
REGEXP_SUBSTR(REGEXP_SUBSTR(COLUMN_NAME, '[^CN=]+',1,1),'[^,OU]+',1,1)
I think there has to be a loop to handle this. Here's SQL Server function that will parse this out. (I know the question didn't specify SQL Server, but it's an example of how it can be done.)
select dbo.ScrubFieldValue(value) from table will return what you're looking for
CREATE FUNCTION ScrubFieldValue
(
#Input varchar(8000)
)
RETURNS varchar(8000)
AS
BEGIN
DECLARE #retval varchar(8000)
DECLARE #charidx int
DECLARE #remaining varchar(8000)
DECLARE #current varchar(8000)
DECLARE #currentLength int
select #retval = ''
select #remaining = #Input
select #charidx = CHARINDEX('CN=', #remaining,2)
while(LEN(#remaining) > 0)
BEGIN
--strip current row from remaining
if (#charidx > 0)
BEGIN
select #current = SUBSTRING(#remaining, 1, #charidx - 1)
END
else
BEGIN
select #current = #remaining
END
select #currentLength = LEN(#current)
-- get current name
select #current = SUBSTRING(#current, 4, CHARINDEX(',OU', #current)-4)
select #retval = #retval + #current + ' '
-- strip off current from remaining
select #remaining =substring(#remaining,#currentLength + 1,
LEN(#remaining) - #currentLength)
select #charidx = CHARINDEX('CN=', #remaining,2)
END
RETURN #retval
END
On my version of DB2 for Z/OS CHARINDEX throws a syntax error. Here are two ways to work around that.
SUBSTRING(ColumnName, 4, INSTR(ColumnName,',',1) - 4)
SUBSTRING(ColumnName, 4, LOCATE_IN_STRING(ColumnName,',') - 4)
I should add that the version is V12R1
If input str is wellformed (i.e. looks like your sample data without any additional tokens such as space), you could use something like:
substr(str,locate('CN=', str)+length('CN='), locate(',', str)-length('CN=')-1)
If your Db2 version support REGEXP, that's a better choice.

Uppercase first two characters in a column in a db table

I've got a column in a database table (SQL Server 2005) that contains data like this:
TQ7394
SZ910284
T r1534
su8472
I would like to update this column so that the first two characters are uppercase. I would also like to remove any spaces between the first two characters. So T q1234 would become TQ1234.
The solution should be able to cope with multiple spaces between the first two characters.
Is this possible in T-SQL? How about in ANSI-92? I'm always interested in seeing how this is done in other db's too, so feel free to post answers for PostgreSQL, MySQL, et al.
Here is a solution:
EDIT: Updated to support replacement of multiple spaces between the first and the second non-space characters
/* TEST TABLE */
DECLARE #T AS TABLE(code Varchar(20))
INSERT INTO #T SELECT 'ab1234x1' UNION SELECT ' ab1234x2'
UNION SELECT ' ab1234x3' UNION SELECT 'a b1234x4'
UNION SELECT 'a b1234x5' UNION SELECT 'a b1234x6'
UNION SELECT 'ab 1234x7' UNION SELECT 'ab 1234x8'
SELECT * FROM #T
/* INPUT
code
--------------------
ab1234x3
ab1234x2
a b1234x6
a b1234x5
a b1234x4
ab 1234x8
ab 1234x7
ab1234x1
*/
/* START PROCESSING SECTION */
DECLARE #s Varchar(20)
DECLARE #firstChar INT
DECLARE #secondChar INT
UPDATE #T SET
#firstChar = PATINDEX('%[^ ]%',code)
,#secondChar = #firstChar + PATINDEX('%[^ ]%', STUFF(code,1, #firstChar,'' ) )
,#s = STUFF(
code,
1,
#secondChar,
REPLACE(LEFT(code,
#secondChar
),' ','')
)
,#s = STUFF(
#s,
1,
2,
UPPER(LEFT(#s,2))
)
,code = #s
/* END PROCESSING SECTION */
SELECT * FROM #T
/* OUTPUT
code
--------------------
AB1234x3
AB1234x2
AB1234x6
AB1234x5
AB1234x4
AB 1234x8
AB 1234x7
AB1234x1
*/
UPDATE YourTable
SET YourColumn = UPPER(
SUBSTRING(
REPLACE(YourColumn, ' ', ''), 1, 2
)
)
+
SUBSTRING(YourColumn, 3, LEN(YourColumn))
UPPER isn't going to hurt any numbers, so if the examples you gave are completely representative, there's not really any harm in doing:
UPDATE tbl
SET col = REPLACE(UPPER(col), ' ', '')
The sample data only has spaces and lowercase letters at the start. If this holds true for the real data then simply:
UPPER(REPLACE(YourColumn, ' ', ''))
For a more specific answer I'd politely ask you to expand on your spec, otherwise I'd have to code around all the other possibilities (e.g. values of less than three characters) without knowing if I was overengineering my solution to handle data that wouldn't actually arise in reality :)
As ever, once you've fixed the data, put in a database constraint to ensure the bad data does not reoccur e.g.
ALTER TABLE YourTable ADD
CONSTRAINT YourColumn__char_pos_1_uppercase_letter
CHECK (ASCII(SUBSTRING(YourColumn, 1, 1)) BETWEEN ASCII('A') AND ASCII('Z'));
ALTER TABLE YourTable ADD
CONSTRAINT YourColumn__char_pos_2_uppercase_letter
CHECK (ASCII(SUBSTRING(YourColumn, 2, 1)) BETWEEN ASCII('A') AND ASCII('Z'));
#huo73: yours doesn't work for me on SQL Server 2008: I get 'TRr1534' instead of 'TR1534'.
update Table set Column = case when len(rtrim(substring (Column , 1 , 2))) < 2
then UPPER(substring (Column , 1 , 1) + substring (Column , 3 , 1)) + substring(Column , 4, len(Column)
else UPPER(substring (Column , 1 , 2)) + substring(Column , 3, len(Column) end
This works on the fact that if there is a space then the trim of that part of string would yield length less than 2 so we split the string in three and use upper on the 1st and 3rd char. In all other cases we can split the string in 2 parts and use upper to make the first two chars to upper case.
If you are doing an UPDATE, I would do it in 2 steps; first get rid of the space (RTRIM on a SUBSTRING), and second do the UPPER on the first 2 chars:
// uses a fixed column length - 20-odd in this case
UPDATE FOO
SET bar = RTRIM(SUBSTRING(bar, 1, 2)) + SUBSTRING(bar, 3, 20)
UPDATE FOO
SET bar = UPPER(SUBSTRING(bar, 1, 2)) + SUBSTRING(bar, 3, 20)
If you need it in a SELECT (i.e. inline), then I'd be tempted to write a scalar UDF

Removing leading zeroes from a field in a SQL statement

I am working on a SQL query that reads from a SQLServer database to produce an extract file. One of the requirements to remove the leading zeroes from a particular field, which is a simple VARCHAR(10) field. So, for example, if the field contains '00001A', the SELECT statement needs to return the data as '1A'.
Is there a way in SQL to easily remove the leading zeroes in this way? I know there is an RTRIM function, but this seems only to remove spaces.
select substring(ColumnName, patindex('%[^0]%',ColumnName), 10)
select replace(ltrim(replace(ColumnName,'0',' ')),' ','0')
You can use this:
SELECT REPLACE(LTRIM(REPLACE('000010A', '0', ' ')),' ', '0')
I had the same need and used this:
select
case
when left(column,1) = '0'
then right(column, (len(column)-1))
else column
end
select substring(substring('B10000N0Z', patindex('%[0]%','B10000N0Z'), 20),
patindex('%[^0]%',substring('B10000N0Z', patindex('%[0]%','B10000N0Z'),
20)), 20)
returns N0Z, that is, will get rid of leading zeroes and anything that comes before them.
If you want the query to return a 0 instead of a string of zeroes or any other value for that matter you can turn this into a case statement like this:
select CASE
WHEN ColumnName = substring(ColumnName, patindex('%[^0]%',ColumnName), 10)
THEN '0'
ELSE substring(ColumnName, patindex('%[^0]%',ColumnName), 10)
END
In case you want to remove the leading zeros from a string with a unknown size.
You may consider using the STUFF command.
Here is an example of how it would work.
SELECT ISNULL(STUFF(ColumnName
,1
,patindex('%[^0]%',ColumnName)-1
,'')
,REPLACE(ColumnName,'0','')
)
See in fiddler various scenarios it will cover
https://dbfiddle.uk/?rdbms=sqlserver_2012&fiddle=14c2dca84aa28f2a7a1fac59c9412d48
You can try this - it takes special care to only remove leading zeroes if needed:
DECLARE #LeadingZeros VARCHAR(10) ='-000987000'
SET #LeadingZeros =
CASE WHEN PATINDEX('%-0', #LeadingZeros) = 1 THEN
#LeadingZeros
ELSE
CAST(CAST(#LeadingZeros AS INT) AS VARCHAR(10))
END
SELECT #LeadingZeros
Or you can simply call
CAST(CAST(#LeadingZeros AS INT) AS VARCHAR(10))
Here is the SQL scalar value function that removes leading zeros from string:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Vikas Patel
-- Create date: 01/31/2019
-- Description: Remove leading zeros from string
-- =============================================
CREATE FUNCTION dbo.funRemoveLeadingZeros
(
-- Add the parameters for the function here
#Input varchar(max)
)
RETURNS varchar(max)
AS
BEGIN
-- Declare the return variable here
DECLARE #Result varchar(max)
-- Add the T-SQL statements to compute the return value here
SET #Result = #Input
WHILE LEFT(#Result, 1) = '0'
BEGIN
SET #Result = SUBSTRING(#Result, 2, LEN(#Result) - 1)
END
-- Return the result of the function
RETURN #Result
END
GO
To remove the leading 0 from month following statement will definitely work.
SELECT replace(left(Convert(nvarchar,GETDATE(),101),2),'0','')+RIGHT(Convert(nvarchar,GETDATE(),101),8)
Just Replace GETDATE() with the date field of your Table.
To remove leading 0, You can multiply number column with 1
Eg: Select (ColumnName * 1)
select CASE
WHEN TRY_CONVERT(bigint,Mtrl_Nbr) = 0
THEN ''
ELSE substring(Mtrl_Nbr, patindex('%[^0]%',Mtrl_Nbr), 18)
END
you can try this
SELECT REPLACE(columnname,'0','') FROM table
I borrowed from ideas above. This is neither fast nor elegant. but it is accurate.
CASE
WHEN left(column, 3) = '000' THEN right(column, (len(column)-3))
WHEN left(column, 2) = '00' THEN right(a.column, (len(column)-2))
WHEN left(column, 1) = '0' THEN right(a.column, (len(column)-1))
ELSE
END
select ltrim('000045', '0') from dual;
LTRIM
-----
45
This should do.