MySQL: Getting a value from a string using a regex? - mysql

One column returns such values:
Something";s:5:"value";s:3:"900";s:11:"print_
I want to extract all numbers that are at least 3 digits long, in the above case thats 900. How can I do that in MySQL? Maybe using a regex? I cant use any index, the length of the string and the number in the string can be different.
Thanks!

Try unserialize() it if you are using PHP! And then var_dump it to see the strings and arrays

You can't extract them using MySQL, use any other language for that.
What you can do is include a Where Clause, that will make the work easier for your script.
Assuming your column is called "serialized" in the table "example"
SELECT serialized FROM example WHERE serialized REGEXP '[0-9]{3,}'
Please note that REGEXP is just outputting 1 or 0
After you did the query, use the regex functions of your language do extract the numbers like so:
([0-9]{3,})*

Related

SQL - match last two characters in a string

I have a small mysql database with a column which has format of a field as following:
x_1_1,
x_1_2,
x_1_2,
x_2_1,
x_2_12,
x_3_1,
x_3_2,
x_3_11,
I want to extra the data where it matches last '_1'. So if I run a query on above sample dataset, it would return
x_1_1,
x_2_1,
x_3_1,
This should not return x_2_12 or x_3_11.
I tried like '%_1' but it returns x_2_12 and x_3_11 as well.
Thank you!
A simple method is the right() function:
select t.*
from t
where right(field, 2) = '_1';
You can use like but you need to escape the _:
where field like '%$_1' escape '$'
Or use regular expressions:
where field regexp '_1$'
The underscore character has special significance in a LIKE clause. It acts as a wildcard and represent one single character. So you would have to escape it with a backslash:
LIKE '%\_1'
RIGHT does the job too, but it requires that you provide the proper length for the string being sought and is thus less flexible.
Duh, I found the answer.
Use RIGHT (col_name, 2) = '_1'
Thank you!

SQL replace all specified keys

I have one column(varchar) containing only json string within one table. I want replace all keys with "" on that column. How can I do that using sql? My database is MySQL.
For example:
|--------------------------------------------------------------------|
| t_column |
|--------------------------------------------------------------------|
| {"name":"mike","email":"xxx#example.com","isManage":false,"age":22}|
|--------------------------------------------------------------------|
SELECT replace(t_column, regexp, "") FROM t_table
I expect:
mikexxx#example.comfalse22
How to write that regexp?
Start from
select t_column->'$.*' from test
This will return a JSON array of attribute values:
[22, "mike", "xxx#example.com", false]
This might be already all you need, and you can try something like
select *
from test
where t_column->'$.*' like '%mike%';
Unfortunately there seems to be no native way to join array values to a single string like JSON_ARRAY_CONCAT(). In MySQL 8.0 you can try REGEXP_REPLACE() and strip all JSON characters:
select regexp_replace(t_column->'$.*', '[" ,\\[\\]]', '') from test
which will return '22mikexxx#example.comfalse'.
If the values can contain one of those characters, they will also be removed.
Note: That isn't very reliable. But it's all I can do in a "simple" way.
See demo on db-fiddle.
I could be making it too simplistic, but this is just a mockup based on your comment. I can formalize it into a query if it fits your requirement.
Let's say you get your JSON string to this format where you replace all the double quotes and curly brackets and then add a comma at the end. After playing with replace and concat_ws, you are now left with:
name:mike,email:xxx#example.com,isManage:false,age:22,
With this format, every value is now preceded by a semicolon and followed by a comma, which is not true for the key. Let's say you now want to see if this JSON string has the value "mike" in it. This, you could achieve using
select * from your_table where json_col like '%:mike,%';
If you really want to solve the problem with your approach then the question becomes
What is the regex that selects all the undesired text from the string {"name":"mike","email":"xxx#example.com","isManage":false,"age":22} ?
Then the answer would be: {\"name\":\"|\"email\":\"|\",\"isManage\":|,\"age\":|}
But as others let you notice I would actually approach the problem parsing JSONs. Look up for functions json_value and json_query
Hope I helped
PS: Keep close attention on how I structured the bolded sentence. Any difference changes the problem.
EDIT:
If you want a more generic expression, something like select all the text that is not a value on a json-formatted string, you can use this one:
{|",|"\w+\":|"|,|}

MYSQL REGEXP with JSON array

I have an JSON string stored in the database and I need to SQL COUNT based on the WHERE condition that is in the JSON string. I need it to work on the MYSQL 5.5.
The only solution that I found and could work is to use the REGEXP function in the SQL query.
Here is my JSON string stored in the custom_data column:
{"language_display":["1","2","3"],"quantity":1500,"meta_display:":["1","2","3"]}
https://regex101.com/r/G8gfzj/1
I now need to create a SQL sentence:
SELECT COUNT(..) WHERE custom_data REGEXP '[HELP_HERE]'
The condition that I look for is that the language_display has to be either 1, 2 or 3... or whatever value I will define when I create the SQL sentence.
So far I came here with the REGEX expression, but it does not work:
(?:\"language_display\":\[(?:"1")\])
Where 1 is replaced with the value that I look for. I could in general look also for "1" (with quotes), but it will also be found in the meta_display array, that will have different values.
I am not good with REGEX! Any suggestions?
I used the following regex to get matches on your test string
\"language_display\":\[(:?\"[0-9]\"\,)*?\"3\"(:?\,\"[0-9]\")*?\]
https://regex101.com/ is a free online regex tester, it seems to work great. Start small and work big.
Sorry it doesn't work for you. It must be failing on the non greedy '*?' perhaps try without the '?'
Have a look at how to serialize this data, with an eye to serializing the language display fields.
How to store a list in a column of a database table
Even if you were to get your idea working it will be slow as fvck. Better off to process through each row once and generate something more easily searched via sql. Even a field containing the comma separated list would be better.

Mysql searching records containing wildcards

I have a table with tens of thousands of VIN numbers. Many of them look along the lines of this:
6MMTL#A423T######
WVWZZZ3BZ1?######
MPATFS27H??######
SCA2D680?7UH#####
SAJAC871?68H06###
The # represents a digit and the ? a letter (A-Z).
I want to search for the following: 6MMTL8A423T000000.
I am struggling to work out the logic. Should I use a function? Should I use mysql regex?
A regular expression match would be a good way to approach this problem. What you need to do is convert the vin expressions into valid regular expressions that represent the logic you've indicated. Here's a simple way to do that:
replace(replace(vin,'#','[0-9]'),'?','[A-Z]')
This would convert 6MMTL#A423T###### into 6MMTL[0-9]A423T[0-9][0-9][0-9][0-9][0-9][0-9]. Now using this converted format, do a regular expression match query:
select vin
from vins
where '6MMTL8A423T000000' regexp replace(replace(vin,'#','[0-9]'),'?','[A-Z]')
Sample Output: 6MMTL#A423T######
Demo: http://www.sqlfiddle.com/#!2/ee4de/4

Extracting information out of a column with regexs in MySQL

Is it possible to get the (first?) match of a regex and output it within a select? It looks like the REGEXP function only return whether there has been a match or not. I want to be able to extract information out of a varchar column without having to use complex SUBSTRING-LOCATION nestings.
Any ideas?
http://dev.mysql.com/doc/refman/5.1/en/regexp.html that's all there is. You can't do more than pattern comparison.