Need regex expression in mysql select query - mysql

I am writing the mysql query where I need to compare data entered by user with the sku column in database tab
Query is like
SELECT *
FROM `is_product_info`
WHERE REPLACE( '-', '', sku ) LIKE '%ETI2006%'
so that if sku in database contains "-" in sku, I am replacing all hyphens with "" before comparing.
so whether sju no contains ETI2006 or ETI-2006, it will come in output

I think you may just like this
SELECT * FROM is_product_info WHERE REPLACE( sku , '-', '' ) LIKE '%ETI2006%'

I didn't try on a running MySQL but this should work:
SELECT *
FROM `is_product_info`
WHERE sku REGEXP REPLACE('ETI-2006','-','-?');

I made the mistake in replace syntax, it works with the below one:
SELECT * FROM is_product_info WHERE REPLACE( sku , '-', '' ) LIKE '%ETI2006%'

Using replace() on every row is what's slowing it down.
All of these approaches should be faster - see which one works best for you:
Option 1 - use LIKE twice:
WHERE sku LIKE '%ETI-2006%'
OR sku LIKE '%ETI2006%'
Option 2 - Use RLIKE once:
WHERE sku RLIKE 'ETI-?2006'

Related

Capture groups in mysql regexp

I have a table with a varchar column that represents a path. I want to search for rows that have a path that follow a pattern like name.name[*] where name can be anything. I am looking for repeated strings contained anywhere in the path column that are separated by a period and have a square bracket after them.
This seems to call for Regexp, so through python I have something like https://regex101.com/r/apS20a/4
However, trying to implement this with MySQL Regexp is not working. I have been able to translate the shorthand into REGEXP '([A-Za-z_]+).(\1[[0-9]+])', but it seems that MySql Regex does not support capture groups. Is there a way to accomplish what I am trying to do with mysql regexp? Thank you
I don't think that MySQL supports capture groups. But if you only have one example of .name[ in the string between the first . and the first [, you can hack your way around it. This is not a general solution, just a specific approach in this case.
You can get the name with:
select substring_index(substring_index(url, '[', 1), '.', -1) as name
And then incorporate this into a regular expression:
select t.*
from (select t.*,
substring_index(substring_index(url, '[', 1), '.', -1) as name
from t
) t
where url like concat('%', name, '.', name, '[%');
This just uses like instead of regexp, because [ and . are regular expression wildcards. Of course, this assumes that name does not have _ or %.
EDIT:
Here is a method that actually identifies when this occurs -- and works even if there are multiple patterns.
The idea is to construct the regular expression based on what happens between the . and [ -- and then to apply it. Delightfully self-referential:
select t.*,
(url regexp regex)
from (select t.*,
substr(regexp_replace(url, '[^.]*[.]([^\\[]*)\\[[^.]*', '|$1[.]$1\\\\['), 2) as regex
from (select 'abcde.de[12345.345[ABC' as url union all
select 'abcdefdef[[[[..123.124['
) t
) t;
Here is the above in a db<>fiddle.

select data mysql

i have in my table places named field. there are space separated values(there are problem to store csv value in one field). now i want to fire query like below. how i can do ??
select * from tablename where variablename in places
i did try this way but it shows syntax error.
select * from tablename where variablename in replace(places,' ',',')
### places ###
bank finance point_of_interest establishment
Use FIND_IN_SET
For comma separated
SELECT *
FROM tablename
WHERE ( FIND_IN_SET( 'bank', variablename ) )
Refer : SQL Fiddle
For space separated
SELECT *
FROM tablename
WHERE ( FIND_IN_SET( 'bank', replace(variablename,' ',',') ) )
Refer : SQL Fiddle
The best solution would be to normalise your data structure and do not have a single field storing multiple values.
You can make a query work without normalisation, but any solutions would be lot less optimal from a performance point of view.
Use patter matching with like operator:
... where fieldname like '% searched_value %'
Use the replace() function and combine it with find_in_set():
... where find_in_set('searched_value',replace(fieldname,' ',','))>0
Hi I think your problem comes from the usage of IN
IN for MySql is used like this
SELECT *
FROM table_name
WHERE column_name IN (bank,finance,point_of_interest, establishment);
In case of you want to select places you need to specify each place into value like

Why is this regexp query not returning any results?

Good day
I have a field that have rows looking like
BBB-888-8557ZZV-003.XYZ
BBB-999-8787ZZV-00D.XYZ
I need to find (and replace after I confirmed that my select returns the correct rows :)) all records that match the regex:
/-\d\d[A-Z]/g
Hence all fields that have a minus sign followed by two digits followed by an alphabet letter.
I also only need to filter out the fields that have 999 in them.
I tried the following SQL but it returns no results:
SELECT *
FROM `track`
WHERE (
pod LIKE "BBB-999%"
AND pod
REGEXP '/-\d\d[A-Z]/g'
)
Also, what will be a quick why to replace all of these fields once they are found to:
BBB-999-8787ZZV-_MARK_D.XYZ
Numbers in mysql shouls be matched like [0-9] or [[:digit:]]
\d wont work as you expected. link
try;
SELECT *
FROM `track`
WHERE
pod LIKE "BBB-999%" and
pod REGEXP '\-[0-9]{2}[A-Z]{1}'
or
SELECT *
FROM `track`
WHERE
pod LIKE "BBB-999%" and
pod REGEXP '\-[[:digit:]]{2}[A-Z]{1}'
sql fiddle demo
Update the field having -00[A-Z].XYZ with -MARK[A_Z].XYZ
Then length of the string is varying (from comment)
last 8 characters can be either \-[0-9]{3}.XYZ or \-[0-9]{2}[A-Z]{1}.XYZ
try:
UPDATE `track`
SET `pod` = concat(reverse(substr(reverse( `pod` ) from 8)), 'MARK', substr( `pod` from -5))
WHERE
`pod` LIKE "BBB-999%" and
`pod` REGEXP '\-0{2}[A-Z]{1}';
sql fiddle demo
You can use the CONCAT() function to get the replacement in the output, after restricting with your query.
SELECT CONCAT(SUBSTRING(pod, 1, LENGTH(pod) - LOCATE('-', REVERSE(pod)) + 1),
'_MARK_D.XYZ')
FROM `track`
WHERE
(
pod LIKE "BBB-999%"
AND pod REGEXP '-[0-9][0-9][A-Z]'
)
For some reason, I needed to use [0-9] in the MySQL regex to get it to work.
Click the link below for a running demo:
SQLFiddle
If you want actually change the values in the pod column you can try an UPDATE:
UPDATE `track`
SET pod = CONCAT(SUBSTRING(pod, 1, LENGTH(pod) - LOCATE('-', REVERSE(pod)) + 1),
'_MARK_D.XYZ')
WHERE
(
pod LIKE "BBB-999%"
AND pod REGEXP '-[0-9][0-9][A-Z]'
)

Use replace with in clause

Got ids stored in DB with Json format like this
'["1454","474","545"]'
I can build list IDs :
SELECT replace
(replace(
replace(
replace('["1454","474","545"]','[','\'')
,']','\'')
,'"','')
,',','\',\'')
mySql returns '1454','474','545'
But when I try to list DB records from this build list of IDs :
SELECT col FROM table WHERE col in (REPLACE
(REPLACE(
REPLACE(
REPLACE('["1454","474","545"]','[','\'')
,']','\'')
,'"','')
,',','\',\''));
mySql says "0 records" even if I add a "SELECT" before the first "REPLACE"
Any help ?
Try below query, you need to add select in your in clause also:
SELECT col FROM table WHERE col in (select REPLACE
(REPLACE(
REPLACE(
REPLACE('["1454","474","545"]','[','\'')
,']','\'')
,'"','')
,',','\',\''));
Alas, you cannot use in with a comma delimited string. It takes a list of elements, but not within a string. So, this works as you expect:
where x in (1,2,3)
This does not work as you expect (although it does work as I expect0;
where x in ('1,2,3')
This looks for one value of x that is the string '1,2,3'.
The solution is to use the MySQL function find_in_set():
SELECT col
FROM table
WHERE find_in_set(col, REPLACE(REPLACE(REPLACE('["1454","474","545"]', '[','\''
), ']', '\''
), '"', ''
), ',', '\',\''
);
To be honest, though, you might be better off with something like:
where '["1454","474","545"]' like concat('%;', col, '&%')

Finding language in string (doing substring?) with MySQL

I have a table with languages which s_name value looks like this:
'en_UK'
'en_US'
'de_CH'
'de_AT'
I want to get all the distinct languages, without the country part. So for example, in case I just had those of the example, I would need to get:
en
de
What would be the best way of doing so?
I have this right now:
SELECT DISTINCT SUBSTRING(name,1,2)
FROM my_languages
Try this:
SELECT DISTINCT SUBSTRING_INDEX(name, '_', 1) langName
FROM my_languages
OR
SELECT SUBSTRING_INDEX(name, '_', 1) langName
FROM my_languages
GROUP BY langName
Check this link MySQL STRING Functions
Here is a simple way:
select distinct left(s_name, 2)
from t
This assumes the language name is the left two characters.
This will work in Oracle as well as in MySql I think:
SELECT SUBSTR('en_UK',INSTR('en_UK','_')+1) country FROM dual
/