10

I am using MySQL 5.7+ with the native JSON data type. Sample data:

[
  {
    "code": 2,
    "stores": [
      {
        "code": 100,
        "quantity": 2
      },
      {
        "code": 200,
        "quantity": 3
      }
    ]
  },
  {
    "code": 4,
    "stores": [
      {
        "code": 300,
        "quantity": 4
      },
      {
        "code": 400,
        "quantity": 5
      }
    ]
  }
]

Question: how do I extract an array where code = 4?

The following (working) query has the position of the data I want to extract and the search criterion hardcoded:

SELECT JSON_EXTRACT(data_column, '$[0]') 
FROM   json_data_table
WHERE  data_column->'$[1].code' = 4

I tried using a wildcard (data_column->'$[*].code' = 4) but I get no results in return.

3 Answers 3

9
SELECT row FROM 
(
    SELECT data_column->"[*]" as row
    FROM   json_data_table
    WHERE  4 IN JSON_EXTRACT(data_column, '$[*].code')
) 
WHERE row->".code" = 4

... though this would be much easier to work with if this wasn't an unindexed array of objects at the top level. You may want to consider some adjustments to the schema.

Note:

If you have multiple rows in your data, specifying "$[i]" will pick that row, not the aggregate of it. With your dataset, "$[1].code" will always evaluate to the value of code in that single row.

Essentially, you were saying:

  1. $ json collection
  2. [1] second object in the collection.
  3. .code attribute labeled "code".

... since there will only ever be one match for that query, it will always eval to 4...

  1. WHERE 4 = 4

Alternate data structure if possible

Since the entire purpose of "code" is as a key, make it the key.

[
  "code2":{
    "stores": [
      {
        "code": 100,
        "quantity": 2
      },
      {
        "code": 200,
        "quantity": 3
      }
    ]
  },
  "code4": {
    "stores": [
      {
        "code": 300,
        "quantity": 4
      },
      {
        "code": 400,
        "quantity": 5
      }
    ]
  }
]

Then, all it would require would be:

SELECT datacolumn->"[code4]" as code4
FROM json_data_table
Sign up to request clarification or add additional context in comments.

8 Comments

It does not return any results. Using WHERE JSON_EXTRACT(data_column, '$[1].code') = 4 works but still hardcodes the object index.
Ah... I think I see what you're asking for... one sec.
Syntax error near 'JSON_EXTRACT(data_column, '$[*].code') ) WHERE row->code = 4' at line 8. How would you modify the JSON object to make it easier to query?
ah... missing quotes.
Thanks. Still an error with quotes. Your other solution makes sense but for a specific use case: finding code. What if I want to search for stores where stores.code = 400 and then select the whole code object. My original question was about finding/selecting objects without knowing their index in a deeply nested JSON. Perhaps the JSON data type is not intended for that purpose?
|
0

This will only return results that have code = 4 at the first level. So it will not find stores->code = 4

SELECT * 
FROM json_data_table 
WHERE JSON_CONTAINS(JSON_EXTRACT(data_column, '$[*].code'), '4')

Hope this helps someone.

Comments

-1

This is what you are looking for.

SELECT data_column->>'$[*]' FROM json_data_table where data_column->>'$[*].cod' = 4.

The selected data will have [] around it when selecting from an array thus data_column->>'$[*].code' = 4 is not possible.

1 Comment

data_column->'$[*].code' like '%4%' would match numbers with a 4 in them

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.