Search code examples
mysqlmysql-json

MySQL JSON - using IN statement | json_contains


I'm trying to select all columns where the roles property in the json column contains ANY of the values.

Statements I've tried:

SELECT * FROM components WHERE json->'$.roles' IN(1)

  • this doesn't even work but it should in my opinion...

SELECT * FROM components WHERE JSON_CONTAINS(components, '1', '$.roles')

  • this does work however is strict, so when I use 1 it pulls both like it should because they both contain 1, however if I insert 1,2 or JSON_ARRAY(1,2) it will only pull the later row because it isn't checking per array element...

I have the following table components structure and data:

+====+========================================================================================================================================================================================================+==+
| id |                                                                                                  json                                                                                                  |  |
+====+========================================================================================================================================================================================================+==+
|  1 | {"area": 1, "roles": [1], "elements": [{"home": {"content": "Home", "attributes": {"class": "my_class_1"}}}, {"dashboard": {"content": "Dashboard", "attributes": {"class": "my_class_1"}}}]}          |  |
+----+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--+
|  2 | {"area": 1, "roles": [1, 2, 5], "elements": [{"home": {"content": "Testing", "attributes": {"class": "my_class_1"}}}, {"dashboard": {"content": "Dashboard", "attributes": {"class": "my_class_1"}}}]} |  |
+----+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--+

Question: How can I modify either of these statements to allow them to query the rows based on the values in the roles property?


Solution

  • The expression

    value in (x, y, z, ...)
    

    is equivalent to

    value = x OR value = y OR value = z OR ...
    

    This doesn't work for an array like json->'$.roles' because an array is not equal to its elements, you need to call JSON_CONTAINS() to test that.

    For what you want, you need to call JSON_CONTAINS() for each value you want to test.

    WHERE JSON_CONTAINS(components, '1', '$.roles') OR JSON_CONTAINS(components, '2', '$.roles')