MySQL 在数组中按键搜索 json 值
MySQL search json value by key in array
我有一个 JSON 对象数组,想要返回一个特定的节点。为了简化我的问题,假设数组看起来像这样:
[
{"Race": "Orc", "strength": 14},
{"Race": "Knight", "strength": 7},
...
]
我想知道骑士的实力。
函数JSON_SEARCH
, returns the path '$[1].Race'
and with the path operator我能得到力量。有没有办法将这两者结合起来,以便我可以执行以下操作?
SELECT someFunc(myCol,'$[*].Race','Orc','$.strength') AS strength
FROM myTable
我正在使用 MySQL 8.0.15.
查看 JSON_CONTAINS (https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#function_json-contains) 并在您的 WHERE 子句中使用它来识别符合您条件的记录。
您实际上是想将 selection and projection 应用于 JSON 文档的数组元素和对象字段。您需要对数组中的 select a "row" 执行 WHERE 子句之类的操作,然后执行诸如选择其中一个字段(不是您在 selection 标准中使用的字段)之类的操作).
这些是在 SQL 中使用 WHERE 子句和 SELECT 列列表完成的,但是用 JSON 做同样的事情不是你可以用函数轻松完成的像 JSON_SEARCH() 和 JSON_CONTAINS().
MySQL 8.0 提供的解决方案是 JSON_TABLE() 函数,可将 JSON 文档转换为虚拟派生 table — 就好像您定义了常规的行和列一样.如果 JSON 是您描述的格式,即对象数组,它会起作用。
这是我通过将您的示例数据插入到 table:
中所做的演示
create table mytable ( mycol json );
insert into mytable set mycol = '[{"Race": "Orc", "strength": 14}, {"Race": "Knight", "strength": 7}]';
SELECT j.* FROM mytable, JSON_TABLE(mycol,
'$[*]' COLUMNS (
race VARCHAR(10) PATH '$.Race',
strength INT PATH '$.strength'
)
) AS j;
+--------+----------+
| race | strength |
+--------+----------+
| Orc | 14 |
| Knight | 7 |
+--------+----------+
现在您可以执行通常使用 SELECT 查询执行的操作,例如 selection 和投影:
SELECT j.strength FROM mytable, JSON_TABLE(mycol, '$[*]'
COLUMNS (
race VARCHAR(10) PATH '$.Race',
strength INT PATH '$.strength'
)
) AS j
WHERE j.race = 'Orc'
+----------+
| strength |
+----------+
| 14 |
+----------+
这有几个问题:
您需要在每次查询JSON数据时执行此操作,或者创建一个VIEW来执行此操作。
您说您不知道属性字段,但是要编写JSON_TABLE() 查询,您必须在查询中指定要搜索和投影的属性。您不能将其用于完全未定义的数据。
我已经回答了很多关于在 MySQL 中使用 JSON 的类似问题。我观察到,当您想做这种事情时,将 JSON 文档视为 table 以便您可以将 WHERE 子句中的条件应用于 JSON 数据中的字段,那么你所有的查询都会变得更加困难。然后您开始觉得最好花几分钟来定义您的属性,这样您就可以编写更简单的查询。
在 SQL 5.7 中有解决这个问题的方法。我将逐步编写解决方案。目标是找到骑士的实力。
我将使用与之前相同的示例 table post:
create table mytable ( mycol json );
insert into mytable set mycol = '[{"Race": "Orc", "strength": 14}, {"Race": "Knight", "strength": 7}]';
首先,获取仅包含种族的数组。
select json_extract(mycol, '$[*].Race') from mytable;
+----------------------------------+
| json_extract(mycol, '$[*].Race') |
+----------------------------------+
| ["Orc", "Knight"] |
+----------------------------------+
然后,在此数组中搜索 Knight(并取消引用)。
select json_unquote(json_search(json_extract(mycol, '$[*].Race'), 'one', 'Knight')) from mytable;
+------------------------------------------------------------------------------+
| json_unquote(json_search(json_extract(mycol, '$[*].Race'), 'one', 'Knight')) |
+------------------------------------------------------------------------------+
| $[1] |
+------------------------------------------------------------------------------+
找到索引后,从数组中获取该元素。
select json_extract(mycol, json_unquote(json_search(json_extract(mycol, '$[*].Race'), 'one', 'Knight'))) from mytable;
+---------------------------------------------------------------------------------------------------+
| json_extract(mycol, json_unquote(json_search(json_extract(mycol, '$[*].Race'), 'one', 'Knight'))) |
+---------------------------------------------------------------------------------------------------+
| {"Race": "Knight", "strength": 7} |
+---------------------------------------------------------------------------------------------------+
然后得到这个元素的强度
select json_extract(json_extract(mycol, json_unquote(json_search(json_extract(mycol, '$[*].Race'), 'one', 'Knight'))), '$.strength') as strength from mytable;
+----------+
| strength |
+----------+
| 7 |
+----------+
您可以在其他字段上重复此操作以创建其他列。
我有一个 JSON 对象数组,想要返回一个特定的节点。为了简化我的问题,假设数组看起来像这样:
[
{"Race": "Orc", "strength": 14},
{"Race": "Knight", "strength": 7},
...
]
我想知道骑士的实力。
函数JSON_SEARCH
, returns the path '$[1].Race'
and with the path operator我能得到力量。有没有办法将这两者结合起来,以便我可以执行以下操作?
SELECT someFunc(myCol,'$[*].Race','Orc','$.strength') AS strength
FROM myTable
我正在使用 MySQL 8.0.15.
查看 JSON_CONTAINS (https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#function_json-contains) 并在您的 WHERE 子句中使用它来识别符合您条件的记录。
您实际上是想将 selection and projection 应用于 JSON 文档的数组元素和对象字段。您需要对数组中的 select a "row" 执行 WHERE 子句之类的操作,然后执行诸如选择其中一个字段(不是您在 selection 标准中使用的字段)之类的操作).
这些是在 SQL 中使用 WHERE 子句和 SELECT 列列表完成的,但是用 JSON 做同样的事情不是你可以用函数轻松完成的像 JSON_SEARCH() 和 JSON_CONTAINS().
MySQL 8.0 提供的解决方案是 JSON_TABLE() 函数,可将 JSON 文档转换为虚拟派生 table — 就好像您定义了常规的行和列一样.如果 JSON 是您描述的格式,即对象数组,它会起作用。
这是我通过将您的示例数据插入到 table:
中所做的演示create table mytable ( mycol json );
insert into mytable set mycol = '[{"Race": "Orc", "strength": 14}, {"Race": "Knight", "strength": 7}]';
SELECT j.* FROM mytable, JSON_TABLE(mycol,
'$[*]' COLUMNS (
race VARCHAR(10) PATH '$.Race',
strength INT PATH '$.strength'
)
) AS j;
+--------+----------+
| race | strength |
+--------+----------+
| Orc | 14 |
| Knight | 7 |
+--------+----------+
现在您可以执行通常使用 SELECT 查询执行的操作,例如 selection 和投影:
SELECT j.strength FROM mytable, JSON_TABLE(mycol, '$[*]'
COLUMNS (
race VARCHAR(10) PATH '$.Race',
strength INT PATH '$.strength'
)
) AS j
WHERE j.race = 'Orc'
+----------+
| strength |
+----------+
| 14 |
+----------+
这有几个问题:
您需要在每次查询JSON数据时执行此操作,或者创建一个VIEW来执行此操作。
您说您不知道属性字段,但是要编写JSON_TABLE() 查询,您必须在查询中指定要搜索和投影的属性。您不能将其用于完全未定义的数据。
我已经回答了很多关于在 MySQL 中使用 JSON 的类似问题。我观察到,当您想做这种事情时,将 JSON 文档视为 table 以便您可以将 WHERE 子句中的条件应用于 JSON 数据中的字段,那么你所有的查询都会变得更加困难。然后您开始觉得最好花几分钟来定义您的属性,这样您就可以编写更简单的查询。
在 SQL 5.7 中有解决这个问题的方法。我将逐步编写解决方案。目标是找到骑士的实力。
我将使用与之前相同的示例 table post:
create table mytable ( mycol json );
insert into mytable set mycol = '[{"Race": "Orc", "strength": 14}, {"Race": "Knight", "strength": 7}]';
首先,获取仅包含种族的数组。
select json_extract(mycol, '$[*].Race') from mytable;
+----------------------------------+
| json_extract(mycol, '$[*].Race') |
+----------------------------------+
| ["Orc", "Knight"] |
+----------------------------------+
然后,在此数组中搜索 Knight(并取消引用)。
select json_unquote(json_search(json_extract(mycol, '$[*].Race'), 'one', 'Knight')) from mytable;
+------------------------------------------------------------------------------+
| json_unquote(json_search(json_extract(mycol, '$[*].Race'), 'one', 'Knight')) |
+------------------------------------------------------------------------------+
| $[1] |
+------------------------------------------------------------------------------+
找到索引后,从数组中获取该元素。
select json_extract(mycol, json_unquote(json_search(json_extract(mycol, '$[*].Race'), 'one', 'Knight'))) from mytable;
+---------------------------------------------------------------------------------------------------+
| json_extract(mycol, json_unquote(json_search(json_extract(mycol, '$[*].Race'), 'one', 'Knight'))) |
+---------------------------------------------------------------------------------------------------+
| {"Race": "Knight", "strength": 7} |
+---------------------------------------------------------------------------------------------------+
然后得到这个元素的强度
select json_extract(json_extract(mycol, json_unquote(json_search(json_extract(mycol, '$[*].Race'), 'one', 'Knight'))), '$.strength') as strength from mytable;
+----------+
| strength |
+----------+
| 7 |
+----------+
您可以在其他字段上重复此操作以创建其他列。