MySQL JSON - 使用IN语句| json_contains

时间:2017-05-31 20:34:58

标签: mysql mysql-json

我尝试选择roles列中json属性包含任意值的所有列。

我试过的陈述:

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

  • 这甚至不起作用,但在我看来应该......

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

  • 这确实有用但是严格,所以当我使用1时,它会两者都拉,因为它们都包含1,但是如果我插入1,2JSON_ARRAY(1,2)它只会拉后一行,因为它不是每个数组元素检查...

我有以下表components 结构数据

+====+========================================================================================================================================================================================================+==+
| 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"}}}]} |  |
+----+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--+

问题:我如何修改其中任何一个语句,以允许他们根据roles属性中的值查询行?

3 个答案:

答案 0 :(得分:3)

表达式

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

相当于

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

这对于像json->'$.roles'这样的数组不起作用,因为数组不等于它的元素,你需要调用JSON_CONTAINS()来测试它。

对于您想要的内容,您需要为要测试的每个值调用JSON_CONTAINS()

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

答案 1 :(得分:0)

请参见https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#function_json-overlaps

JSON_OVERLAPS(json_doc1, json_doc2)

比较两个JSON文档。如果两个文档具有共同的任何键值对或数组元素,则返回true(1)。如果两个参数都是标量,则该函数将执行简单的相等性测试。

此功能与JSON_CONTAINS()相对,后者要求要搜索的数组的所有元素都出现在要搜索的数组中。因此,JSON_CONTAINS()对搜索键执行AND操作,而{ {1}}执行“或”运算。

可以使用多值索引来优化在WHERE子句中使用JSON_OVERLAPS()对InnoDB表的JSON列的查询。多值索引,提供了详细的信息和示例。

比较两个数组时,JSON_OVERLAPS()如果它们共享一个或多个数组元素,则返回true;否则,则返回false。

JSON_OVERLAPS()

答案 2 :(得分:0)

尝试其中一种应该起作用

SELECT * FROM components WHERE JSON_CONTAINS([1],  roles, '$');

SELECT * FROM components WHERE JSON_CONTAINS([1],  CAST(roles as JSON), '$');