How does select SUBSTRING('uppercase ', LEN('uppercase')-2, 3) result in "ase" - sql

Please see below query:
select SUBSTRING('uppercase ', LEN('uppercase')-2, 3)
Can someone explain how it is working and giving output as ase
Please help.

SUBSTRING function extracts characters from a string. In additon,LEN function provide the length of string. the LEN('uppercase') would be 9.
SUBSTRING(string, start, length)
your query is like
select SUBSTRING('uppercase ', LEN('uppercase')-2, 3)---equivalent
select SUBSTRING('uppercase ', 9-2, 3) --equivalent
select SUBSTRING('uppercase ', 7, 3)
hence it provide ase

Should be:
select SUBSTRING('uppercase ', LENGTH('uppercase')-2, 3) // Mysql hasn't len function
LENGTH('uppercase') // return 9, the length of string.
SUBSTRING('uppercase ', 9-2, 3) // return a substring from the index of 7 and three characters, that is ase

Go through the documentation of substring function
SUBSTRING ( expression ,start , length )
expression
Is a character, binary, text, ntext, or image expression.
start
Is an integer or bigint expression that specifies where the
returned characters start. (The numbering is 1 based, meaning that the
first character in the expression is 1). If start is less than 1, the
returned expression will begin at the first character that is
specified in expression. In this case, the number of characters that
are returned is the largest value of either the sum of start + length-
1 or 0. If start is greater than the number of characters in the value
expression, a zero-length expression is returned.
length
Is a positive integer or bigint expression that specifies how
many characters of the expression will be returned. If length is
negative, an error is generated and the statement is terminated. If
the sum of start and length is greater than the number of characters
in expression, the whole value expression beginning at start is
returned.
In your case,
SUBSTRING('uppercase ', LEN('uppercase')-2, 3)
SUBSTRING('uppercase ', 9-2, 3)
SUBSTRING('uppercase ', 7, 3)
u p p e r c a s e
1 2 3 4 5 6 7 8 9
<====> (From 7 pick 3 characters)
a s e

Related

How to remove just the numeric data to fields

We have data that will be entered into a table, and right now it comes as [68.0,00.2]. I want to lose the [ ] at the front and end, and no comma, put the numeric info into different fields. When I try something like what I have below:
Select SUBSTRING('[68.0,00.2]', 2,CHARINDEX(',','[68.0,00.2]')-2) as cpu_01,
SUBSTRING('[68.0,00.2]', CHARINDEX(',','[68.0,00.2]')+1,
(LEN('[68.0,00.0]')-1)) as cpu_02
I get:
cpu_01 cpu_02
68.0 00.2]
Why can I not get rid of that last ] ??
I don't recommend the method you're using to split a string, but to answer your specific question of why you get the bracket:
The final parameter of SUBSTRING() is length, you're treating it as if it were the ending position.
SUBSTRING ( expression ,start , length )
length Is a positive integer or bigint expression that specifies how
many characters of the expression will be returned. If length is
negative, an error is generated and the statement is terminated. If
the sum of start and length is greater than the number of characters
in expression, the whole value expression beginning at start is
returned.
This would work:
Select SUBSTRING('[68.0,00.2]', 2,CHARINDEX(',','[68.0,00.2]')-2) as cpu_01,
SUBSTRING('[68.0,00.2]', CHARINDEX(',','[68.0,00.2]')+1,
(LEN('[68.0,00.0]')-CHARINDEX(',','[68.0,00.2]'))-1) as cpu_02
I would use apply for this type of operation:
select left(v1.str, charindex(',', v1.str) - 1),
stuff(v1.str, 1, charindex(',', v1.str), '')
from (values ('[68.0,00.2]')) v(str) cross apply
(values (replace(replace(v.str, '[', ''), ']', ''))) v1(str);
This first gets rid of the '[' and ']'. Then it uses string manipulations to split the value.
Because you are - with 1 if you use this :
Select SUBSTRING('[68.0,00.2]', 2,CHARINDEX(',','[68.0,00.2]')-2) as cpu_01,
SUBSTRING('[68.0,00.2]', CHARINDEX(',','[68.0,00.2]')+1,
(LEN('[68.0,00.2]')-7)) as cpu_02
You will see the result which you need.
LEN('[68.0,00.2]) =11
So If you add -7 you will get true answer.
result :
cpu_01 cpu_02
68.0 00.2

Strange phenomenon with substring and charindex

When comparing the code snippets below, you can see that the last element of the 'result 1' result set, only has one character (a comma) appending the number, whereas the other numbers (rows 1 - 3) have a comma and a number appending the 4 digits that I want.
In the 'Result 2' result set, I specifically change the length of the substring to be the string length minus two characters, yet the last element only removes a single element, the trailing comma, while the rows 1 - 3 remove both the number and the trailing comma. There is no blank space in the last row. Please could someone advise why this is happening?
Code 1:
select substring(c,2,charindex(',',c,2)) as empno
from table t
where len(c) > 1
and substring(c,1,1) = ','
Result 1:
7654,7
7698,7
7782,7
7788,
Code 2:
select substring(c,2,charindex(',',c,2)-2) as empno
from table t
where len(c) > 1
and substring(c,1,1) = ','
Result 2:
7654
7698
7782
7788
*edit: table t is:-
c
----------------------
,7654,7698,7782,7788,
7654,7698,7782,7788,
654,7698,7782,7788,
54,7698,7782,7788,
4,7698,7782,7788,
,7698,7782,7788,
7698,7782,7788,
698,7782,7788,
98,7782,7788,
8,7782,7788,
,7782,7788,
7782,7788,
782,7788,
82,7788,
2,7788,
,7788,
7788,
788,
88,
8,
,
CHARINDEX:
Returns part of a character, binary, text, or image expression in SQL Server.
is defined as:
CHARINDEX ( expressionToFind , expressionToSearch [ , start_location ] )
AND
SUBSTRING:
Returns part of a character, binary, text, or image expression in SQL Server.
is defined as:
SUBSTRING ( expression ,start , length )
Query1:
substring(c,2,charindex(',',c,2))
In above charIndex returns first position of ',' i.e. 6 in every case.
So the returned value is acting as length for the substring which is 6 and that's why you are getting each record of 6 lengths.
Query 2:
substring(c,2,charindex(',',c,2)-2)
In above charIndex returns first position of ',' i.e. 6 in every case. But also you are reducing the length by subtracting 2 from it.
So the returned value is acting as length for the substring which is 4 now and that's why you are getting each record of 4 lengths in this query.
See this query1 and query2 represent CHARINDEX returned values:
c query1 query2
,7654,7698,7782,7788, 6 4
,7698,7782,7788, 6 4
,7782,7788, 6 4
,7788, 6 4

sql query about string function

ID MOBILE
1 9869600733
2 9869600793
3 9869600799
all id whose mobile number containing 9 three times(using string functions like replace, substr, etc)... ? (without like , % , etc)
You can use LEN and Replace
Where len(MOBILE)-len(replace(MOBILE ,'9',''))>=3
Note : Some DBMS uses LENGTH instead of LEN
Where length(MOBILE)-length(replace(MOBILE ,'9',''))>=3
DEMO
replace(MOBILE ,'9','') will replace all the 9's with empty
string
length(MOBILE) will count the number of characters in Mobile
column
length(replace(MOBILE ,'9','')) will count the number of characters
in Mobile column as replacing 9's with empty string
length(MOBILE)-length(replace(MOBILE ,'9','')) here the
difference will tell the number of missing characters that is our 9, you can use this difference to count the 9
exactly three '9's:
Select * from mytable
Where len(mobile) - len(replace(mobile, '9', '')) = 3
at least three '9's:
Select * from mytable
Where len(mobile) - len(replace(mobile, '9', '')) >= 3

How to replace character in SQL

I want to Replace a particular character on position 4 in sql Server ,
i know about replace or case when but my problem is that i just want to 4th position character replace ,
i am trying like
SELECT REPLACE(_NAME,0,1) AS exp FROM _EMPLOYEE
but it will not cheching 4th character
for example if _name contain IMR002001 then it should be IMR012001
Use stuff():
select stuff(_NAME, 4, 1, '#')
This replaces the substring starting at position 4 with length 1 with the string that is the fourth argument. The string can be longer or shorter than the string being replaced.
For your example:
select stuff(_NAME, 4, 1, '1')

Remove leading zeros

Given data in a column which look like this:
00001 00
00026 00
I need to use SQL to remove anything after the space and all leading zeros from the values so that the final output will be:
1
26
How can I best do this?
Btw I'm using DB2
This was tested on DB2 for Linux/Unix/Windows and z/OS.
You can use the LOCATE() function in DB2 to find the character position of the first space in a string, and then send that to SUBSTR() as the end location (minus one) to get only the first number of the string. Casting to INT will get rid of the leading zeros, but if you need it in string form, you can CAST again to CHAR.
SELECT CAST(SUBSTR(col, 1, LOCATE(' ', col) - 1) AS INT)
FROM tab
In DB2 (Express-C 9.7.5) you can use the SQL standard TRIM() function:
db2 => CREATE TABLE tbl (vc VARCHAR(64))
DB20000I The SQL command completed successfully.
db2 => INSERT INTO tbl (vc) VALUES ('00001 00'), ('00026 00')
DB20000I The SQL command completed successfully.
db2 => SELECT TRIM(TRIM('0' FROM vc)) AS trimmed FROM tbl
TRIMMED
----------------------------------------------------------------
1
26
2 record(s) selected.
The inner TRIM() removes leading and trailing zero characters, while the outer trim removes spaces.
This worked for me on the AS400 DB2.
The "L" stands for Leading.
You can also use "T" for Trailing.
I am assuming the field type is currently VARCHAR, do you need to store things other than INTs?
If the field type was INT, they would be removed automatically.
Alternatively, to select the values:
SELECT (CAST(CAST Col1 AS int) AS varchar) AS Col1
I found this thread for some reason and find it odd that no one actually answered the question. It seems that the goal is to return a left adjusted field:
SELECT
TRIM(L '0' FROM SUBSTR(trim(col) || ' ',1,LOCATE(' ',trim(col) || ' ') - 1))
FROM tab
One option is implicit casting: SELECT SUBSTR(column, 1, 5) + 0 AS column_as_number ...
That assumes that the structure is nnnnn nn, ie exactly 5 characters, a space and two more characters.
Explicit casting, ie SUBSTR(column,1,5)::INT is also a possibility, but exact syntax depends on the RDBMS in question.
Use the following to achieve this when the space location is variable, or even when it's fixed and you want to make a more robust query (in case it moves later):
SELECT CAST(SUBSTR(LTRIM('00123 45'), 1, CASE WHEN LOCATE(' ', LTRIM('00123 45')) <= 1 THEN LEN('00123 45') ELSE LOCATE(' ', LTRIM('00123 45')) - 1 END) AS BIGINT)
If you know the column will always contain a blank space after the start:
SELECT CAST(LOCATE(LTRIM('00123 45'), 1, LOCATE(' ', LTRIM('00123 45')) - 1) AS BIGINT)
both of these result in:
123
so your query would
SELECT CAST(SUBSTR(LTRIM(myCol1), 1, CASE WHEN LOCATE(' ', LTRIM(myCol1)) <= 1 THEN LEN(myCol1) ELSE LOCATE(' ', LTRIM(myCol1)) - 1 END) AS BIGINT)
FROM myTable1
This removes any content after the first space character (ignoring leading spaces), and then converts the remainder to a 64bit integer which will then remove all leading zeroes.
If you want to keep all the numbers and just remove the leading zeroes and any spaces you can use:
SELECT CAST(REPLACE('00123 45', ' ', '') AS BIGINT)
While my answer might seem quite verbose compared to simply SELECT CAST(SUBSTR(myCol1, 1, 5) AS BIGINT) FROM myTable1 but it allows for the space character to not always be there, situations where the myCol1 value is not of the form nnnnn nn if the string is nn nn then the convert to int will fail.
Remember to be careful if you use the TRIM function to remove the leading zeroes, and actually in all situations you will need to test your code with data like 00120 00 and see if it returns 12 instead of the correct value of 120.