I have a json which looks like this:
"{\"chat:title\":\"Random name Comunidad\",\"chat:type\":\"supergroup\",\"command:start:count\":4,\"command:start:ts\":1648146227630,\"command:help:count\":1,\"command:help:ts\":1648145742922,\"command:price:count\":3,\"command:price:ts\":1648146698585}"
And I'd like to query it and get the name out of it. I tried classically:
SELECT metadata->>'chat'
SELECT metadata->>'chat:title'
but it's not working. I think it's because of the backslash in the string... Any ideas how to query it?
Just remove backslash from the string:
with t as (
select '{\"chat:title\":\"Random name Comunidad\",\"chat:type\":\"supergroup\",\"command:start:count\":4,\"command:start:ts\":1648146227630,\"command:help:count\":1,\"command:help:ts\":1648145742922,\"command:price:count\":3,\"command:price:ts\":1648146698585}'
as metadata)
select replace(t.metadata, '\','')::json ->> 'chat:title'
from t
Is it of JSON type and the content is as is you showed? If so then:
select btrim(replace(metadata::text,'\',''),'"')::json->>'chat:title';
Manually removing the backslashes might work, but will eventually fail on some inputs and just make things worse.
The right way is to use the existing JSON operators to fix it (unless of course someone has already made it worse).
SELECT (metadata->>0)::jsonb ->> 'chat:title'
But really you should fix the source that is causing the problem, and update the existing data to store the fix.
update whatever set metadata=(metadata->>0)::jsonb;
If only some of the data has been crappified, you might need to where clause to distinguish the good from the bad and so only fix the bad.
Related
I am trying to make sort of a search engine that searched through JSON values in my Database.
I have a table with a column called data in data there is a JSON string, example:
{"type_geld":"cash","bedrag":15.0,"totaal":8899.0,"reden":"itemshop-bought-item","citizenid":"EHT44095","steamnaam":"Finn"}
Now I want to search through the key steamnaam I am currently using this query:
SELECT * FROM logs_1 WHERE JSON_CONTAINS(lower(`data`), '"finn"', "$.steamnaam")
This does give me the rows that contain finn as a value in the steamname JSON.
But now I want to also make it check if it's not exactly the same, but almost the same. So basically a LIKE search. Can I achieve this with JSON_CONTAINS or something like that?
So if I type fin instead of finn I also want it to list the rows because it almost matches finn.
I tried a lot of things, but could not figure it out, hope someone has the solution for me! Thank you.
The solution I found:
Apparently after googling a bit more, I found this query, that exactly does what I want:
SELECT * FROM logs_1 WHERE JSON_EXTRACT(lower(`data`), "$.steamnaam") LIKE "%fin%"
The only concern I have if this will stay fast with a lot of rows..
SELECT *
FROM logs_1
WHERE data->>'$.steamnaam' LIKE '%fin%' /* COLLATE according CI collation */
I have some fields in a MYSQL database with the following content:
eq":"fieldname1+fieldname2+fieldname3+fieldname4/4
The numbers are always different, so it could also be something like:
eq":"fieldname11+fieldname22+fieldname8/10
I would like to run a query to achieve the following:
eq":"((fieldname1+fieldname2+fieldname3+fieldname4)/4, 2)
I currently have the following query
UPDATE wp_wrdydtdbww_cp_calculated_fields_form_settings
SET form_structure = REPLACE(form_structure, '???', '???')
WHERE id IN (1,2,3);
The problem is, that there are a lot of additional strings, containing 'fieldname' or '/' as well, so I need to replace the exact structure.
Can somebody help me to modify it?
I tried something with the LIKE pattern (%), but can't get it to work as I always replace other parts of strings as well.
Thanks!
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+\":|"|,|}
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.
I'm trying to replace all instances of an old BB tag markup in a MySql database with a newer, slightly different one.
The old format is this...
[youtube:********]{Video ID}[/youtube:********]
Which I would like to replace with this...
[youtube:********]http://www.youtube.com/watch?v={Video ID}[/youtube:********]
Where the *'s are a random string of alpha-numeric characters. So simply REPLACE(feild, '[youtube:********]', '[youtube:********]http://www.youtube.com?watch?v= won't do unfortunately.
All the clumsy attempts I've made using REPLACE() and INSTR() have resulted in nasty things like [b]Bold Text[/b]http://www.youtube.com/watch?v=
Is there a way to do this kind of pattern replacement in MySql? Possibly with Regular Expressions?
Thank you.
Is this what you tried?
UPDATE table SET Field = REPLACE(Field,']{',']http://www.youtube.com/watch?v={')
This would depend if there isnt any other occurences of ']{'
EDIT: You may also want to try:
UPDATE table SET Field = LEFT(Field,#) + 'http://www.youtube.com/watch?v='+
RIGHT(Field,(Char_Length(Field)-#);
Just check the syntax with MYSQl docs. Char_LNEGTH() may need to be LENGTH() - im sure you get the idea