How do I search nested json query in mysql? - mysql

I am using MySQL 5.7+ with the native JSON data type.
Sample data:
set #jsn_string='{\"body\": {\"items\": \"[{\\\"count\\\":530,\\\"id\\\":5},{\\\"count\\\":1,\\\"id\\\":519},{\\\"count\\\":209,\\\"id\\\":522},{\\\"count\\\":0,\\\"id\\\":3004}] \"}}';
Questions: the correct answer is 530
The following query has the position of the data
select json_extract(#jsn_string,'$.body.items[0].id[0]');
but the result is : null

we can use json_unquote to remove those double quotes in items[0]
set #jsn_string='{\"body\": {\"items\": \"[{\\\"count\\\":530,\\\"id\\\":5},{\\\"count\\\":1,\\\"id\\\":519},{\\\"count\\\":209,\\\"id\\\":522},{\\\"count\\\":0,\\\"id\\\":3004}] \"}}';
select json_extract(json_unquote(json_unquote(json_extract(#jsn_string, '$.body.items[0]')))
,'$[0].count');
see dbfiddle

As per your sample JSON, id is not an array. So id[0] wont work As I understand from your question, you want to retrieve 530. For this you can use the following.
select json_extract(#jsn_string,'$.body.items[0].count');
Please let me know if I understood it incorrectly.
Edit - 1:
I think your json is invalid. Array should not be wrapped in braces. Try this
#jsn_string='{\"body\": {\"items\": [{\\\"count\\\":530,\\\"id\\\":5},{\\\"count\\\":1,\\\"id\\\":519},{\\\"count\\\":209,\\\"id\\\":522},{\\\"count\\\":0,\\\"id\\\":3004}]}}';

Related

How to extract the value from the string in BigQuery

I have the following value as String in one column in bigquery table. I need to extract the content value using BigQuery view.
{type:System.Int32,content:202104}
I have converted the string like below and tried the JSON_EXTRACT syntax its working.
SELECT
JSON_EXTRACT(JSON'{"type":"System.Int32","content":202104}', '$.content')
AS json_data;
But I have converted this manually from
{type:System.Int32,content:202104}
to
{"type":"System.Int32","content":202104}
How can I achieve the same using query? Can anyone help me to resolve this query, Thanks in advance!
You may use REGEXP_EXTRACT to directly extract the value of the "content". Please refer to BigQuery REGEXP_EXTRACT for more information on the usage of this string function.
SELECT REGEXP_EXTRACT('{type:System.Int32,content:202104}', r'content:(\d+)') as CONTENT_EXTRACT
Output:
This may help:
SELECT
JSON_EXTRACT_SCALAR(REGEXP_REPLACE('{type:System.Int32,content:202104}', r'[^\:\,{}]+', r'"\0"'), '$.content')
AS json_data

How to Extract JSON from MySql

I want to extract the new status value from the below JSON
{"old_status":"Testing(PhaseI)","new_status":"Production(PhaseII)","user":"Developer","reason":null}
so the output required is Production(PhaseII), pls note that the new_status's values are completely dynamic , how to do this using JSON_EXTRACT()
SELECT JSON_UNQUOTE(JSON_EXTRACT(`field``, '$.new_status'))

MySQL query from JSON datatype column that has backslash character

I have a difficulty to query element in JSON column in MySQL
This is my data :
example of whats in the column :
{\order\":[{\"product_id\":3,\"quantity\":5,\"product_name\":\"Ikan salmon bakar \"}]}"
I'm using this sql syntax :
SELECT JSON_EXTRACT(order_list, '$.order[*].product_id') FROM orders_copy WHERE id = 3;
If I use this query to the column that contain backslash, then it will produce null.
Expected result (eg:) :
I'm not sure if I should get rid of the backslash so that the query will produce result or is there any effective way solving it ?.
Thanks a lot
I found the answers for problem I stated above.
It is just that I found the answer through this link : https://dev.mysql.com/doc/refman/5.7/en/json-modification-functions.html#function_json-replace , where I search for what are the code that are compatible with MySQL version to cater special character. For backslash, I'm using JSON_UNQUOTE()
Here I put the solution : https://www.db-fiddle.com/f/i7EpX4Qq86iJWFkPgzMhVX/0
Thanks to those who help:)
You can remove the backslash using REPLACE() and make the main query to become a sub-query before the JSON_EXTRACT function take place. Try this query:
SELECT JSON_EXTRACT(od, '$.order[*].product_id')
FROM
(SELECT *, REPLACE(order_list,'\\','') AS od FROM orders_copy WHERE id = 3) A;
And here's an example fiddle: https://dbfiddle.uk/?rdbms=mariadb_10.3&fiddle=6f52caffa6c97bbcfcc18bb5fb713348

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.