0

I have text field in MySQL 5.6 table which consists string representation of JSON. Such JSONs exist field "clients" with array of ID's, e.g.:

{
    ...
    "clients":[1,2,3],
    ...
}

How to write SQL query which prints exactly this part of text from JSON for every record, e.g.:

clients
-----------------
"clients":[1,2,3]
"clients":[4,5]
...

Should I use some kind of regex or it could be done easier?

Thank you!

UPDATE: JSON_EXTRACT doesn't work for MySQL 5.6

3 Answers 3

4

Don't use regex to parse JSON, instead use the JSON_EXTRACT function:

SELECT JSON_EXTRACT(json, "$.clients")
FROM yourTable;

Demo

Using regex to parse JSON is generally a bad idea unless there is no alternative. In this case, more recent versions of MySQL offer a JSON API which can handle your requirement.

Sign up to request clarification or add additional context in comments.

9 Comments

Thank you for quick response! The difficulty is that type of data is "text", not "json" and I can't change it, so that I have to handle it as a plain string
This should not matter, and if you view the demo, you will see that the JSON functions can also operate on plain text, so long as that plain text be valid JSON.
"I have text field in MySQL 5.6 table which consists string representation of JSON" One problem i believe MySQL 5.6 does not support native JSON functions or does not have great JSON support, the more modern 5.6 versions might have it
Seems like it doesn't work for MySQL 5.6 :( [42000][1305] FUNCTION authdb.JSON_EXTRACT does not exist
Yes, you could try to do that. But keep in mind as soon as your JSON structure changes, your query could break. Also appreciate that the order of fields in JSON can move around without changing the logical equivalence of the JSON.
|
1

Well i strongly advice upgrading, this query is more meant for fun.

Query

SELECT 
 DISTINCT 
  SUBSTRING_INDEX(
    SUBSTRING_INDEX(
        records.cvs
      , ','
      , number_generator.number
    )
    , ','
    , -1
  ) array_part
FROM (
 SELECT 
 @row := @row + 1 AS number
FROM (
  SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
) row1
CROSS JOIN (
  SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
) row2
CROSS JOIN (
  SELECT @row := 0 
) init_user_params 
) AS number_generator
CROSS JOIN (


SELECT 
  # parse out the 1,2,3 part from  [1,2,3] part
  SUBSTRING (
     # parse out the [1,2,3] part
     SUBSTRING(
         records.json
       , (LOCATE(':', records.json) + 1)
     )
   , 2 
   , LENGTH(
      # parse out the [1,2,3] part
      SUBSTRING(
         records.json
       , (LOCATE(':', records.json) + 1)
       )
     ) - 2
 ) AS cvs
FROM (
  SELECT  
    '"clients":[1,2,3]' AS json
) AS records

) AS records

Result

| array_part |
| ---------- |
| 1          |
| 2          |
| 3          |

see demo

4 Comments

Looks a bit complicated, I just need to cut "clients":[...] slice from string, I started from "select substr(json, instr(json, '"clients":['))" but stucked how to get index of first ] symbol after "clients":[
indeed @DmitryAdonin that's why you should upgrade. i use SUBSTRING in combination with LOCATE to parse out the json array part and a SQL number generator to parse the 1,2,3 string into real records with nested STRING_INDEX functions.
also @DmitryAdonin why don't you play around with the example and make it more simple to see what the parts are doing?
It's a shame but I don't understand half of this example :)
1

Must be processed from SQL? I think it is more rational to process outside SQL server. Or you can upgrade your MySQL to 5.7.8+ and use JSON_EXTRACT. Everything else will be a BIG crutch.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.