Substring from last index - mysql

ABC:123 UVW XYZ NN-000
What is the best method to get the value after the last space using substr()? In this case I want to get NN-000 but also be able to get that last value in the case that it's greater than or less than 6 characters.

In Oracle, use SUBSTR and INSTR functions
SELECT SUBSTR('ABC:123 UVW XYZ NN-000', INSTR('ABC:123 UVW XYZ NN-000', ' ', -1))
AS LASTOCCUR
FROM DUAL
RESULT:
| LASTOCCUR |
-------------
| NN-000 |
Refer LIVE DEMO

In MySQL you could use reverse and substring_index:
select data,
rv,
reverse(substring_index(rv, ' ', 1)) yd
from
(
select data,
reverse(data) rv
from yt
) d;
See SQL Fiddle with Demo
In Oracle you could use reverse, substr and instr:
select data,
reverse(substr(rv, 0, instr(rv, ' '))) rv
from
(
select data, reverse(data) rv
from yt
) d
See SQL Fiddle with Demo

Combine the powers of RIGHT(),REVERSE() AND LOCATE()
SELECT RIGHT('ABC:123 UVW XYZ NN-000',LOCATE(' ',REVERSE('ABC:123 UVW XYZ NN-000'))-1)
EDIT: Locate in MYSQL, not CHARINDEX
REVERSE() reverses the string, so that the 'first' space it finds is really the last one. You could use SUBSTRING instead of RIGHT, but if what you're after is at the end of the string, might as well use RIGHT.

Related

How to extract specifc part from a string in MySQL

I am trying to extract a specifc part from a string in MySQL, however, I am unable to extract it correctly.
The pattern is the following:
-MB|{field_1}-AA|{field_2}-BB|{field_3}
This is the example
-MB|string1-AA|string2-BB|string3
I've written the following code to extract the last field, however it is not dynamic, and will only work, when we have a specific number of letters/numbers:
SELECT
test_string,
SUBSTRING(test_string, LOCATE( '|', test_string) + 1 - LOCATE( '|', test_string) - 9) as string3
FROM test_table;
The output is the whole string and then just the last part of it:
string3
Having this said, can someone suggest a syntax that I can use in order to extract:
the values between the 1st | and second |
the value between the 2nd | and the 3rd |
and a better way to extract everything after the 3rd |
Thank you in advance!
If you're going for the last string only, you can REVERSE() the string first then locate | and then use it to do SUBSTRING() on the reversed string.. THEN reverse it again to get the original string. There are three REVERSE() in total if you're going with SUBSTRING() without a subquery:
SELECT test_string,
REVERSE(SUBSTRING(REVERSE(test_string),1,LOCATE('|',REVERSE(test_string))-1))
FROM test_table;
If you're using a subquery, you can reduce the usage of REVERSE() to two, albeit with a longer query:
SELECT test_string,
REVERSE(SUBSTRING(rvstr,1,LOCATE('|',rvstr)-1))
FROM
(SELECT test_string,
REVERSE(test_string) rvstr
FROM test_table) a;
But you can avoid all that and just use SUBSTRING_INDEX
SELECT test_string,
SUBSTRING_INDEX(test_string, '|', -1)
FROM test_table;
You can use the same function to extract other string separated by the delimiter using something like this:
SELECT test_string,
SUBSTRING_INDEX(SUBSTRING_INDEX(test_string,'|',1),'|',-1) AS 'Str1',
SUBSTRING_INDEX(SUBSTRING_INDEX(test_string,'|',2),'|',-1) AS 'Str2',
SUBSTRING_INDEX(SUBSTRING_INDEX(test_string,'|',3),'|',-1) AS 'Str3'
FROM test_table;
As for "way to extract everything after the 3rd", I think it's a bit tricky but maybe:
SELECT test_string,
Str1,Str2,Str3,
SUBSTRING(test_string,LENGTH(CONCAT(Str1,Str2,Str3))+4) AS 'StrAfter3rd'
FROM
(SELECT test_string,
SUBSTRING_INDEX(SUBSTRING_INDEX(test_string,'|',1),'|',-1) AS 'Str1',
SUBSTRING_INDEX(SUBSTRING_INDEX(test_string,'|',2),'|',-1) AS 'Str2',
SUBSTRING_INDEX(SUBSTRING_INDEX(test_string,'|',3),'|',-1) AS 'Str3'
FROM test_table) v;
Getting the LENGTH() of the concatenated results of Str1 to Str3 with 3 of the original | re-added and + the last | before the 4th string (+4 in total), then use it for the SUBSTRING().
Demo fiddle

sql extract only numeric value from column

I have a column called' memo_line_2',the value format is like :'$3000.00 (card limit increase)',how can I only extract numeric value from the column?Thanks
example:
'$3000.00 (card limit increase)' -> 3000
'$5000.00 (card limit increase)' -> 5000
'$12000.00 (card limit increase)' ->12000
You could use REGEXP_SUBSTR() for this:
SELECT REGEXP_SUBSTR(tmp.`value`, '[0-9]+') as `new_value`
FROM (SELECT '$3000.00' as `value` UNION ALL
SELECT '$5000.00' as `value` UNION ALL
SELECT '$12000.00' as `value`) tmp
Returns:
new_value
---------
3000
5000
12000
If you would like to keep everything after the decimal, use '[0-9.]+' as your regular expression filter.
If your data will be always in this format you can use below query to select the data between $ and . :
SELECT substring_index(substring_index(memo_line_2, '$', -1), '.', 1)
FROM your_table;
Refrence: MySQL substring between two strings
You can use:
select regexp_substr(col, '[0-9]+[.]?[0-9]*')
This will extract the digits with the cents. You can then convert to an integer or numeric:
select cast(regexp_substr(col, '[0-9]+[.]?[0-9]*') as unsigned)
It can be done by making a custom function in your sql query
Take a look at:
https://stackoverflow.com/a/37269038/16536522

MYSQL : Find the last occurrence of a character in a string

Length will be dynamic and i want to find the data before last occurrence of a character in a string in MYSQL
Like strrchr in php
To get last occurrence of _ (underscore) I need to pass length. and here it's 3
mysql> SELECT SUBSTRING_INDEX ('this_is_something_here', '_', 3);
+----------------------------------------------------+
| SUBSTRING_INDEX ('this_is_something_here', '_', 3) |
+----------------------------------------------------+
| this_is_something |
+----------------------------------------------------+
And here, to get last occurrence of _ (underscore) i need to pass length. and here it's 6
mysql> SELECT SUBSTRING_INDEX ('and_this_may_go_like_this_too', '_', 6);
+-----------------------------------------------------------+
| SUBSTRING_INDEX ('and_this_may_go_like_this_too', '_', 6) |
+-----------------------------------------------------------+
| and_this_may_go_like_this |
+-----------------------------------------------------------+
i want data string before last occurrence of _ (underscore) just shown in above example but without passing length.
Note : from above example i want before data of "_here" and "_too"
last occurrence of _ (underscore)
Is there any built-in functionality to achieve this in MySQL?
Thanks in advance amigos.
I didn't quite get your examples, but I think what you want is to pass -1 as the length and prepend the substring prior.
Compare
strrchr('and_this_may_go_like_this_too', '_'); // Returns _too
SELECT SUBSTRING_INDEX('and_this_may_go_like_this_too', '_', -1);
-- Returns too, just need to concatenate `_` so...
SELECT CONCAT('_', SUBSTRING_INDEX('and_this_may_go_like_this_too', '_', -1));
-- Returns _too
If you're looking for the part of the string before and up to the needle, and not from the needle to the end of the string, you can use:
SET #FULL_STRING = 'this_is_something_here';
SELECT LEFT(#FULL_STRING, LENGTH(#FULL_STRING) - LOCATE('_', REVERSE(#FULL_STRING)));
-- Returns this_is_something
Note that the second statement is not what strrchr does.
select reverse(substr(reverse('this_is_something_here'), 1+locate('_', reverse('this_is_something_here'))));
Use reverse, locate, right then replace without using length
Set #str = 'there_is_something';
Select replace(#str,right(#str,locate('_',reverse(#str))),'');
You can write query like this
SELECT SUBSTRING_INDEX('and_this_may_go_like_this_too','_',(LENGTH('and_this_may_go_like_this_too')-LENGTH(REPLACE('and_this_may_go_like_this_too' ,'_',''))) - 1);

Trying to specific values from a mysql column

I have a mysql (text)column that contains all comments with hash tags and I'm looking for a way to select only the hash tags
Id | Column
1 | I'm #cool and #calm
2 | l like #manchester
3 | #mysql troubles not #cool
You can sort of do what you want by using substring_index() to do the parsing. Assuming that the character after the hash tag is a space, you can do:
select t.*,
substring_index(substring_index(comment, '#', n.n + 1), ' ', 1)
from table t join
(select 1 as n union all select 2 union all select 3) n
on n.n <= length(t.comment) - length(replace(t.comment, '#', '')) ;
The fancy on clause is counting the number of # in the comment, which is counting the number of tags.
You can use Regular Expressions
Try this Regular Expression:
/(#[A-Za-z])\w+
Demo:
[http://regexr.com/3a2q7][1]

MySQL order varchar alpha-numerically

Given a VARCHAR column called title with the following SELECT title FROM table ORDER BY title results:
Alpha 11
Alpha 2
Beta 1
Beta 11
Beta 2
I would like this to be in the "correct" order of
Alpha 2
Alpha 11
Beta 1
Beta 2
Beta 11
Is there a way to do this?
Try this:
SELECT title ,
SUBSTRING_INDEX(title, '', 1) as title_str,
SUBSTRING_INDEX(title, ' ', -1) + 0 as title_num
FROM table
ORDER BY title_str,
title_num
This is called Natural Order sorting. Unfortunately there is no such sort algorithm built-in to MySQL, so your most reliable bet would be to create a UDF to do it for you.
However, this question has an interesting answer:
Here is a quick solution:
SELECT title
FROM table
ORDER BY LENGTH(title), title
Try this:
SELECT title
FROM tablename
ORDER BY SUBSTRING_INDEX(title, ' ', 1),
CAST(SUBSTRING_INDEX(title, ' ', -1) AS UNSIGNED);