MYSQL: Get substring from column value? - mysql

I have the following Varchar data in a column in my MYSQL table:
Blank_Person_ID_776
Person_999
I want to extract the final number after the underscore to a variable (in this case 776) in order to use it in a query. I.e. ignore any underscore but the last one.
How can I do so?
I would like my final query to be as follows:
SET #personId= //query to get id;
Update Person set tracking_id = #personId where tracking_id is null;

If you want the final value after the last '_', use substring_index():
select substring_index(<whatever>, '_', -1)
If you specifically want the final number in the string, even when there are characters after:
select regexp_replace(<whatever>, '.*_([0-9]+)[^0-9]*$', '$1')

Related

How to find the longest matching string from a input string

A table, named strings, contains various strings, and unique id's:
Question is, how to write a query that takes an input string, and return the id of the longest matching (sub) string in the strings table?
The matching string, may, or may not be a substring of the input string. Comparison starts at string index 0.
Inputs and expected output:
INPUT -> OUTPUT
ABC -> 1
ABCD -> 2
ABCKK -> 1
ABCDDD -> 2
DAB -> NULL
CDE -> NULL
Doing this:
SET #theString = 'ABCBBB';
SELECT id FROM strings WHERE a_string LIKE #theString;
only returns the correct result when the input string exactly matches a string in the table, and don't work when the 'a_string' is a substring.
You can use:
select s.*
from strings s
where #theString regexp a_string
order by length(a_string) desc
limit 1;
In regards of using LIKE, you need to set the wildcards for it to work as the filter you want. If you are not required to set a variable, you can use the following query.
SELECT id FROM strings
WHERE a_string LIKE '%ABC%'
ORDER BY length(a_string) DESC LIMIT 1;
or if you need a variable, it can be done with the CONCAT function
SELECT id FROM strings
WHERE a_string LIKE CONCAT('%',#theString,'%')
ORDER BY length(a_string) DESC LIMIT 1;
This just is an alternative to #Gordon Linoff's answer.

MySQL get value from string with char_length()

I have a column that consists of details of an orderline named 'ConcatValue'. An example of a value in this column is:
573856014/100/M00558640/OrderQty12
I want to extract the order value which can be founded after 'OrderQty'. I thought I had a solution by executing the following statement: substr(ConcatValue,char_length(ConcatValue)-1,char_length(ConcatValue))
This results in only level the last 2 characters of the string from the column ConcatValue. For the ConcatValue mentioned above I will get the following result: '12'. Which is the desired result.
But when the orderline has an Order quantity below 10, for example in the following ConcatValue:573856014/100/M00558640/OrderQty3
I will get the following result: y3
My question: Is there a way to delete 'y' if a row has an y within the value? Or is there a way to replace the y with a 0? Or is there a way to only select the last digits from the ConcatValue string?
Use string functions.
With substring_index() you can get the last part of the string and with replace() remove 'OrderQty':
select replace(
substring_index(ConcatValue, '/', -1),
'OrderQty',
''
)
from tablename
Actually, the simplest method is simply:
select substring_index(ConcatValue, 'OrderQty', -1)

How to sort the string on the basis of numbers?

I am working on the sql query in which I want to sort the string on the basis of numbers.
I have one column (Column Name is Name) table in which there are multiple fields. On using ORDER BY NAME, it prints in the following way:
hello_world
hello_world10
hello_world11
hello_world12
hello_world13
hello_world14
hello_world15
hello_world4
hello_world5
For the above query, I have used ORDER BY NAME; but it doesn't seem to print on the basis of numbers.
Problem Statement:
I am wondering what sql query I need to write or what changes I need to make in my sql query above so that it prints everything on the basis of numbers, the o/p should be this:
hello_world
hello_world4
hello_world5
hello_world10
hello_world11
hello_world12
hello_world13
hello_world14
hello_world15
you want a numeric ordering, then you need to create a numeric value to order on.
currently you have strings.
if the pattern is true, then you can use a combination of string manipulation to trim off the first characters, which should leave only numbers, then use TO_NUMBER() to convert for the ordering
something like
select name
from mytable
order by to_number( replace( name, 'hello_world','' ))
I think the simplest solution for this particular case (where all the values have the same prefix) is:
order by length(name), name
Try this:
SELECT name,
CASE WHEN REGEXP_INSTR(name, '[0-9]') = 0 THEN 0
ELSE CAST(SUBSTR(name, REGEXP_INSTR(name, '[0-9]')) AS INT)
END AS progressive
FROM my_table
ORDER BY progressive;
we can order it using replace and cast methods.
I tried the following query
select Name, cast(REPLACE(Name, 'hello_world', '') as UNSIGNED ) as repl from Users order by repl;
To generage sample data
CREATE TABLE Users (
Name varchar(255) NOT NULL
);
insert into Users(Name) values
('hello_world'),
('hello_world4'),
('hello_world5'),
('hello_world10'),
('hello_world11'),
('hello_world12'),
('hello_world13'),
('hello_world14'),
('hello_world15')
;
EDIT
query without replaced column,
select City from Persons order by cast(REPLACE(City, 'hello_world', '') as UNSIGNED );
Though the question is about mysql.
I tried in sql server.
create table #t1 (id varchar(100));
insert into #t1 (id) values ('Pq1'),('pq3'),('pq2')
select * from #t
order by
CAST(SUBSTRING(id + '0', PATINDEX('%[0-9]%', id + '0'), LEN(id + '0')) AS INT)

MySQL returned an empty result set (i.e. zero rows) where expecting more then zero rows

SELECT username FROM `info` WHERE id
in ('919953990950_1403180247868.707,
919953990950_1403239797121.525,
919953990950_1403241821083.838,
919953990950_1403248486971.661,
919953990950_1403248511255.484,
919953990950_1403248860947.79,
919953990950_1403255594277.013') and username !='1403176452487620892' limit 50
this is not selecting rows what's wrong in my query?
You need to enclose each value in single quotes, not the entire list:
SELECT username
FROM `info`
WHERE id in ('919953990950_1403180247868.707',
'919953990950_1403239797121.525',
'919953990950_1403241821083.838',
'919953990950_1403248486971.661',
'919953990950_1403248511255.484',
'919953990950_1403248860947.79',
'919953990950_1403255594277.013'
) and
username <> '1403176452487620892'
limit 50;
Try this by putting every value in quotes '' else it would consider the entire as one string and also replace != with <>:
SELECT username
FROM `info`
WHERE id
in ('919953990950_1403180247868.707',
'919953990950_1403239797121.525',
'919953990950_1403241821083.838',
'919953990950_1403248486971.661',
'919953990950_1403248511255.484',
'919953990950_1403248860947.79',
'919953990950_1403255594277.013') and username <>'1403176452487620892'
OP's comment:
i am inserting it by scala language thats a string
Use find_in_set when set of values are in the form of a comma separated values
SELECT username FROM `info`
WHERE FIND_IN_SET( id, csv_values )
AND username !='1403176452487620892' limit 50;
In the above example replace 'csv_values' with the string of values received from SCALA
I suggest you to go with Prepared Statement to bind values.
Refer to:
FIND_IN_SET( str, strlist )
Return the index position of the first argument within the second
argument

search in MySQL database based on alphabet's position?

I want to search in my database "emp" for names which have the alphabet "A" as third alphabet from left in their names.
This is what I tried:
select empname from emp
where left(empname,3)="a"
order by empname;
It returns an empty set.
Can you check my syntax, whether it is correct or not!
(Upvote promised ;) )
left(empname,3) will return the three leftmost characters in the string.
You need substring(empname,3,1), which will start at the third character and return a string of length 1.
The reference is here
Your query becomes:
select empname from emp
where substring(empname,3,1)="a"
order by empname;
The INSTR() function returns the position of the first occurrence of a string in another string. This function performs a case-insensitive search.
Select INSTR(first_name, 'm') from Tablename where first_name = 'monika';
Reference:- https://www.w3schools.com/sql/func_mysql_instr.asp