内置函数--json类型

2020-12-25
JSON_TYPE(json)

返回json类型,可以是对象,数组或标量类型;如果不是json类型返回错误

JSON_ARRAY(value1,value2,...)

JSON_ARRAY(1,2,'a');
-- ["a", 1, "2015-07-27 09:43:47.000000"]

返回包含value值的JSON数组

JSON_OBJECT(key1,value1,key2,value2,...)

JSON_OBJECT('key1', 1, 'key2', 'abc'); 
-- {"key1": 1, "key2": "abc"}

返回包含这些键值对的JSON对象;重复的键的成员将被丢弃(即使值不同)

JSON_MERGE(json_doc, json_doc[, json_doc] ...)

JSON_MERGE('["a", 1]', '{"key": "value"}'); 
-- ["a", 1, {"key": "value"}] 

返回两个或多个JSON数据合并的结果 (5.7.22弃用)

合并时,多个对象将生成一个对象。如果多个对象具有相同的键,则在合并后的对象中该键的值是一个包含所有键值的数组

mysql> SELECT JSON_MERGE('{"a": 1, "b": 2}', '{"c": 3, "a": 4}');
+----------------------------------------------------+
| JSON_MERGE('{"a": 1, "b": 2}', '{"c": 3, "a": 4}') |
+----------------------------------------------------+
| {"a": [1, 4], "b": 2, "c": 3}                      |
+----------------------------------------------------+

合并数组与对象,通过将对象自动包装为数组并将两个数组合并

mysql> SELECT JSON_MERGE('[10, 20]', '{"a": "x", "b": "y"}');
+------------------------------------------------+
| JSON_MERGE('[10, 20]', '{"a": "x", "b": "y"}') |
+------------------------------------------------+
| [10, 20, {"a": "x", "b": "y"}]                 |
+------------------------------------------------+

合并两个json值

每个值用[]括起来,并将其转换为数组,再进行合并

mysql> SELECT JSON_MERGE('1', '2');
+----------------------+
| JSON_MERGE('1', '2') |
+----------------------+
| [1, 2]               |
+----------------------+
JSON_MERGE_PATCH(json_doc, json_doc[, json_doc] ...)

返回两个或多个JSON文档合并的结果,不会保留具有重复键的成员,在MySQL 5.7.22和更高版本中受支持

返回结果规则:

  • 如果第一个参数不是对象,则合并的结果为空对象与第二个参数合并的结果
    mysql> SELECT JSON_MERGE_PATCH('[1, 2]', '[true, false]');
    +---------------------------------------------+
    | JSON_MERGE_PATCH('[1,2]','[true,false]')| 
    + --------------------------------------------- + 
    | [true,false] | 
    + --------------------------------------------- + 
    
    mysql> SELECT JSON_MERGE_PATCH('[1, 2]', '{"id": 47}');
    + -------------- ---------------------------- + 
    | JSON_MERGE_PATCH('[1,2]','{“ id”:47}')| 
    + ------------------------------------------ + 
    | {“ id”:47} | 
    + ------------------------------------------ + 
  • 如果第二个参数不是对象,则合并的结果为第二个参数。
    mysql> SELECT JSON_MERGE_PATCH('1', 'true');
    + ------------------------------- + 
    | JSON_MERGE_PATCH('1','true' )| 
    + ------------------------------- + 
    | true|
    + ------------------------------- + 
  • 如果两个参数都是对象,则合并的结果是具有以下成员的对象:
    • 在第二个对象中,第一个对象的所有成员都没有具有相同键的对应成员。
    • 第二个对象的所有成员,在第一个对象中没有对应的键,并且其值不是JSON null文字
    • 具有第一个和第二个对象中都存在且其第二个对象中的值不是null的键的所有成员。这些成员的值是将第一个对象中的值与第二个对象中的值递归合并的结果
mysql> SELECT JSON_MERGE_PATCH('{"name": "x"}', '{"id": 47}');
+ ------------------------------------------------- + 
| JSON_MERGE_PATCH('{“ name”:“ x”}','{“ id”:47}')| 
+ ------------------------------------------------- + 
| {“ id”:47,“name”:“ x”} | 
+ ------------------------------------------------- + 

mysql SELECT JSON_MERGE_PATCH('{ "a": 1, "b":2 }','{ "a": 3, "c":4 }');
+- -------------------------------------------------- ------- + 
| JSON_MERGE_PATCH('{“ a”:1,“ b”:2}','{“ a”:3,“ c”:4}')| 
+ ------------------------------------------------- ---------- + 
| {“ a”:3,“ b”:2,“ c”:4} | 
+ ------------------------------------------------- ---------- + 

mysql>SELECT JSON_MERGE_PATCH('{ "a": 1, "b":2 }','{ "a": 3, "c":4 }','{ "a": 5, "d":6 }');
+ ------------------------------------------------- ------------------------------ + 
| JSON_MERGE_PATCH('{“ a”:1,“ b”:2}','{“ a”:3,“ c”:4}','{“ a”:5,“ d”:6}') | 
+ ------------------------------------------------- ------------------------------ + 
| {“ a”:5,“ b”:2,“ c”:4,“ d”:6} | 
+ ------------------------------------------------- ------------------------------ + 
JSON_MERGE_PRESERVE(json_doc, json_doc[, json_doc] ...)

返回两个或多个JSON文档合并的结果,如果任何参数为NULL,则返回NULL

返回结果规则:

  • 相邻数组合并为单个数组。
  • 相邻对象合并为单个对象。
  • 标量值将自动包装为数组,然后合并为数组。
  • 通过将对象自动包装为一个数组并将两个数组合并,可以合并相邻的数组和对象。
SELECT JSON_MERGE_PRESERVE('{ "a": 1, "b": 2 }','{ "a": 3, "c": 4 }','{ "a": 5, "d": 6 }');
+ -------------------------------- -------------------------------------------------- + 
| JSON_MERGE_PRESERVE('{“ a”:1,“ b”:2}','{“ a”:3,“ c”:4}','{“ a”:5,“ d”:6}') | 
+ ------------------------------------------------- --------------------------------- + 
| {“ a”:[1、3、5],“ b”:2,“ c”:4,“ d”:6}
+ ------------------------------------------------- --------------------------------- + 
JSON_OBJECTAGG(key, value)

将两个列名称或表达式用作参数,其中第一个用作键,第二个用作值,并返回包含键值对的JSON对象

mysql> SELECT o_id, attribute, value FROM t3;
+------+-----------+-------+
| o_id | attribute | value |
+------+-----------+-------+
|    2 | color     | red   |
|    2 | fabric    | silk  |
|    3 | color     | green |
|    3 | shape     | square|
+------+-----------+-------+
4 rows in set (0.00 sec)

mysql> SELECT o_id, JSON_OBJECTAGG(attribute, value)
     > FROM t3 GROUP BY o_id;
+------+---------------------------------------+
| o_id | JSON_OBJECTAGG(attribute, value)      |
+------+---------------------------------------+
|    2 | {"color": "red", "fabric": "silk"}    |
|    3 | {"color": "green", "shape": "square"} |
+------+---------------------------------------+
JSON_EXTRACT(json_doc, path[, path] ...)

从JSON文档中提取指定键的成员,如果在路径表达式(path)中不带引号的名称不合法(例如,如果包含空格),则必须在双引号中指定键名称

mysql> SELECT JSON_EXTRACT('{"id": 14, "name": "Aztalan"}', '$.name');
+---------------------------------------------------------+
| JSON_EXTRACT('{"id": 14, "name": "Aztalan"}', '$.name') |
+---------------------------------------------------------+
| "Aztalan"                                               |
+---------------------------------------------------------+
JSON_SET(json_doc, path, val[, path, val] ...)

在JSON文档中插入或更新数据并返回结果

使用新值覆盖现有文档值中现有路径-值对。如果路径中标识以下类型的值之一,则文档中不存在的路径-值对会将值添加到文档中:

  • 现有对象中不存在的成员。成员被添加到对象并与新值关联。
  • 超出现有数组末尾的位置。用新值扩展数组。如果现有值不是数组,则将其自动包装为数组,然后使用新值进行扩展
mysql> SET @j = '["a", {"b": [true, false]}, [10, 20]]';
mysql> SELECT JSON_SET(@j, '$[1].b[0]', 1, '$[2][2]', 2);
+--------------------------------------------+
| JSON_SET(@j, '$[1].b[0]', 1, '$[2][2]', 2) |
+--------------------------------------------+
| ["a", {"b": [1, false]}, [10, 20, 2]]      |
+--------------------------------------------+
JSON_INSERT()

添加新值,但不替换现有值

mysql> SET @j = '["a", {"b": [true, false]}, [10, 20]]';
mysql> SELECT JSON_INSERT(@j, '$[1].b[0]', 1, '$[2][2]', 2);
+-----------------------------------------------+
| JSON_INSERT(@j, '$[1].b[0]', 1, '$[2][2]', 2) |
+-----------------------------------------------+
| ["a", {"b": [true, false]}, [10, 20, 2]]      |
+-----------------------------------------------+
JSON_REPLACE(json_doc, path, val[, path, val] ...)

替换JSON文档中的现有值并返回结果

mysql> SET @j = '["a", {"b": [true, false]}, [10, 20]]';
mysql> SELECT JSON_REPLACE(@j, '$[1].b[0]', 1, '$[2][2]', 2);
+------------------------------------------------+
| JSON_REPLACE(@j, '$[1].b[0]', 1, '$[2][2]', 2) |
+------------------------------------------------+
| ["a", {"b": [1, false]}, [10, 20]]             |
+------------------------------------------------+
JSON_REMOVE(json_doc, path[, path] ...)

从JSON文档中删除数据并返回结果。如果任何参数为NULL,则返回NULL;如果json_doc参数不是有效的JSON文档,或者任何路径参数不是有效的路径表达式,或者是$或包含*或**通配符,则会发生错误;如果要删除的元素在文档中不存在,没有错误

mysql> SET @j = '["a", {"b": [true, false]}, [10, 20]]';
mysql> SELECT JSON_REMOVE(@j, '$[2]', '$[1].b[1]', '$[1].b[1]');
+---------------------------------------------------+
| JSON_REMOVE(@j, '$[2]', '$[1].b[1]', '$[1].b[1]') |
+---------------------------------------------------+
| ["a", {"b": [true]}]                              |
+---------------------------------------------------+
JSON_ARRAY_APPEND(json_doc, path, val[, path, val] ...)

将值附加到JSON文档中指定数组的末尾并返回结果。有任何NULL参数则返回 NULL,json_doc参数不是有效的JSON文档,或者任何path参数不是有效的路径表达式,或者$包含*或**通配符,或者不以数组元素标识符结尾,则会发生错误 

mysql> SET @j = '["a", ["b", "c"], "d"]';
mysql> SELECT JSON_ARRAY_APPEND(@j, '$[1]', 1);
+ ---------------------------------- + 
| JSON_ARRAY_APPEND(@j,'$[1]',1)| 
+ ---------------------------------- + 
| [“ a”,[“ b”,“ c”,1],“ d”] | 
+ ---------------------------------- + 
JSON_ARRAY_INSERT(json_doc, path, val[, path, val] ...)

更新JSON文档,将其插入文档中的数组中并返回修改后的文档;有任何NULL参数则返回NULL,json_doc参数不是有效的JSON文档,或者任何path参数不是有效的路径表达式,或者$包含*或**通配符,或者不以数组元素标识符结尾,则会发生错误;路径无法标识JSON文档中任何数组的对将被忽略。如果路径标识数组元素,则在该元素位置插入相应的值,然后将任何后续值向右移动。如果路径标识了超出数组末尾的数组位置,则将值插入到数组末尾。

mysql> SET @j = '["a", {"b": [1, 2]}, [3, 4]]';
mysql> SELECT JSON_ARRAY_INSERT(@j, '$[1]', 'x');
+------------------------------------+
| JSON_ARRAY_INSERT(@j, '$[1]', 'x') |
+------------------------------------+
| ["a", "x", {"b": [1, 2]}, [3, 4]]  |
+------------------------------------+
mysql> SELECT JSON_ARRAY_INSERT(@j, '$[100]', 'x');
+--------------------------------------+
| JSON_ARRAY_INSERT(@j, '$[100]', 'x') |
+--------------------------------------+
| ["a", {"b": [1, 2]}, [3, 4], "x"]    |
+--------------------------------------+
mysql> SELECT JSON_ARRAY_INSERT(@j, '$[1].b[0]', 'x');
+-----------------------------------------+
| JSON_ARRAY_INSERT(@j, '$[1].b[0]', 'x') |
+-----------------------------------------+
| ["a", {"b": ["x", 1, 2]}, [3, 4]]       |
+-----------------------------------------+
mysql> SELECT JSON_ARRAY_INSERT(@j, '$[0]', 'x', '$[2][1]', 'y');
+----------------------------------------------------+
| JSON_ARRAY_INSERT(@j, '$[0]', 'x', '$[2][1]', 'y') |
+----------------------------------------------------+
| ["x", "a", {"b": [1, 2]}, [3, 4]]                  |
+----------------------------------------------------+
JSON_ARRAYAGG(col_or_expr)

将结果集聚合为一个JSON数组,其元素由行组成。这个数组中元素的顺序没有定义。该函数作用于计算结果为单个值的列或表达式。如果结果不包含任何行,或者发生错误,则返回NULL。

mysql> SELECT o_id, attribute, value FROM t3;
+------+-----------+-------+
| o_id | attribute | value |
+------+-----------+-------+
|    2 | color     | red   |
|    2 | fabric    | silk  |
|    3 | color     | green |
|    3 | shape     | square|
+------+-----------+-------+
4 rows in set (0.00 sec)

mysql> SELECT o_id, JSON_ARRAYAGG(attribute) AS attributes
     > FROM t3 GROUP BY o_id;
+------+---------------------+
| o_id | attributes          |
+------+---------------------+
|    2 | ["color", "fabric"] |
|    3 | ["color", "shape"]  |
+------+---------------------+
JSON_CONTAINS(target, candidate[, path])

判断给定的值candidate是否包含在JSON文档target中,包含返回1,否则返回0,如果提供了路径参数则在目标中的特定路径上验证,如果任何参数为空,或者path参数没有标识目标文档的某个部分,则返回NULL。如果target或candidate不是有效的JSON文档,或者path参数不是有效的路径表达式,或者包含*或**通配符,则会发生错误。

JSON_CONTAINS_PATH(json_doc, one_or_all, path[, path] ...)

指示JSON文档是否包含给定路径上的数据,包含返回1,否则返回0;有任何参数NULL则返回null,如果json_doc参数不是有效的JSON文档,任何路径参数都不是有效的路径表达式,或者one_or_all不是'one'或'all',则会发生错误。

mysql> SET @j = '{"a": 1, "b": 2, "c": {"d": 4}}';
mysql> SELECT JSON_CONTAINS_PATH(@j, 'one', '$.a', '$.e');
+---------------------------------------------+
| JSON_CONTAINS_PATH(@j, 'one', '$.a', '$.e') |
+---------------------------------------------+
|                                           1 |
+---------------------------------------------+
mysql> SELECT JSON_CONTAINS_PATH(@j, 'all', '$.a', '$.e');
+---------------------------------------------+
| JSON_CONTAINS_PATH(@j, 'all', '$.a', '$.e') |
+---------------------------------------------+
|                                           0 |
+---------------------------------------------+
JSON_DEPTH(json_doc)

JSON文档的最大深度,空数组,空对象或标量值的深度为1;仅包含深度1的元素的非空数组或仅包含深度1的成员值的非空对象的深度为2。否则,JSON文档的深度大于2

JSON_KEYS(json_doc[, path])

以JSON数组的形式返回JSON对象的顶级值中的键,或者,如果提供了path 参数,则返回所选路径中的顶级键

mysql> SELECT JSON_KEYS('{"a": 1, "b": {"c": 30}}');
+ --------------------------------------- + 
| JSON_KEYS('{“ a”:1,“ b”:{“ c”:30}}')| 
+ --------------------------------------- + 
| [“ a”,“ b”] | 
+ --------------------------------------- + 
mysql> SELECT JSON_KEYS('{"a": 1, "b": {"c": 30}}', '$.b');
+ ------ ---------------------------------------- + 
| JSON_KEYS('{“ a”:1,“ b”:{“ c”:30}}','$ .b')| 
+ ---------------------------------------------- + 
| [“ c”] | 
+ ---------------------------------------------- +
JSON_LENGTH(json_doc[, path])

返回JSON文档的长度,如果提供了path参数,则返回由路径标识的文档中值的长度;标量的长度为1。数组的长度是数组元素的数量。对象的长度是对象成员的数量。该长度不计算嵌套数组或对象的长度。

JSON_PRETTY(json_val)

打印json值,在MySQL 5.7.22中添加。

mysql> SELECT JSON_PRETTY('123'); # scalar
+--------------------+
| JSON_PRETTY('123') |
+--------------------+
| 123                |
+--------------------+

mysql> SELECT JSON_PRETTY("[1,3,5]"); # array
+------------------------+
| JSON_PRETTY("[1,3,5]") |
+------------------------+
| [
  1,
  3,
  5
]      |
+------------------------+

mysql> SELECT JSON_PRETTY('{"a":"10","b":"15","x":"25"}'); # object
+---------------------------------------------+
| JSON_PRETTY('{"a":"10","b":"15","x":"25"}') |
+---------------------------------------------+
| {
  "a": "10",
  "b": "15",
  "x": "25"
}   |
+---------------------------------------------+
JSON_VALID(val)

返回0或1以指示值是否有效JSON。如果参数为NULL则返回NULL。

JSON_SEARCH(json_doc, one_or_all, search_str[, escape_char[, path] ...])

返回JSON文档中给定字符串的路径,

one_or_all参数会影响搜索,如下所示:

  • one:搜索在第一个匹配项后终止,并返回一个路径字符串。未定义首先考虑哪个匹配。
  • all:搜索将返回所有匹配的路径字符串,因此不包括重复的路径。如果有多个字符串,它们将自动包装为一个数组。数组元素的顺序是不确定的。
mysql> SET @j = '["abc", [{"k": "10"}, "def"], {"x":"abc"}, {"y":"bcd"}]';

mysql> SELECT JSON_SEARCH(@j, 'one', 'abc');
+-------------------------------+
| JSON_SEARCH(@j, 'one', 'abc') |
+-------------------------------+
| "$[0]"                        |
+-------------------------------+

mysql> SELECT JSON_SEARCH(@j, 'all', 'abc');
+-------------------------------+
| JSON_SEARCH(@j, 'all', 'abc') |
+-------------------------------+
| ["$[0]", "$[2].x"]            |
+-------------------------------+
JSON_STORAGE_SIZE(json_val)

返回用于存储JSON文档的二进制表示形式的字节数。当参数为JSON列时,这是用于返回存储JSON文档的空间。如果参数是字符串,该函数将通过将字符串解析为JSON并将其转换为二进制来创建JSON二进制表示形式,以返回存储空间量

JSON_QUOTE(string)
mysql> SELECT JSON_QUOTE('null'), JSON_QUOTE('"null"');
+--------------------+----------------------+
| JSON_QUOTE('null') | JSON_QUOTE('"null"') |
+--------------------+----------------------+
| "null"             | "\"null\""           |
+--------------------+----------------------+
mysql> SELECT JSON_QUOTE('[1, 2, 3]');
+-------------------------+
| JSON_QUOTE('[1, 2, 3]') |
+-------------------------+
| "[1, 2, 3]"             |
+-------------------------+

通过用双引号字符将字符串包装并转义内部引号和其他字符来将utf8mb4字符串引为JSON值,然后将结果作为字符串返回。如果参数为NULL,则返回NULL。
此函数通常用于生成有效的JSON字符串文字,以包含在JSON文档中

路径表达式

路径可以包含*或 **通配符

.*  返回JSON对象中所有成员的值

mysql> SELECT JSON_EXTRACT('{"a": 1, "b": 2, "c": [3, 4, 5]}', '$.*');
+---------------------------------------------------------+
| JSON_EXTRACT('{"a": 1, "b": 2, "c": [3, 4, 5]}', '$.*') |
+---------------------------------------------------------+
| [1, 2, [3, 4, 5]]                                       |
+---------------------------------------------------------+

[*] 返回JSON数组中所有元素的值。

mysql> SELECT JSON_EXTRACT('{"a": 1, "b": 2, "c": [3, 4, 5]}', '$.c[*]');
+------------------------------------------------------------+
| JSON_EXTRACT('{"a": 1, "b": 2, "c": [3, 4, 5]}', '$.c[*]') |
+------------------------------------------------------------+
| [3, 4, 5]                                                  |
+------------------------------------------------------------+

prefix**suffix 返回所有以命名前缀开头并以命名后缀结尾的路径的值。

mysql> SELECT JSON_EXTRACT('{"a": {"b": 1}, "c": {"b": 2}}', '$**.b');
+---------------------------------------------------------+
| JSON_EXTRACT('{"a": {"b": 1}, "c": {"b": 2}}', '$**.b') |
+---------------------------------------------------------+
| [1, 2]                                                  |
+---------------------------------------------------------+
set @j = '[3, {"a": [5, 6], "b": 10}, [99, 100]]';
mysql> SELECT JSON_EXTRACT(@j, $[1].a),JSON_EXTRACT(@j, $[1].a[1]),JSON_EXTRACT(@j, $[1].b),JSON_EXTRACT(@j, $[2][0]);
+---------------------------------------------+
| JSON_EXTRACT(@j, $[1].a)                    |
+---------------------------------------------+
| [5, 6]                                      |
+---------------------------------------------+
| JSON_EXTRACT(@j, $[1].a[1])                 |
+---------------------------------------------+
| 6                                           |
+---------------------------------------------+
| JSON_EXTRACT(@j, $[1].b)                    |
+---------------------------------------------+
| 10                                          |
+---------------------------------------------+
| JSON_EXTRACT(@j, $[2][0])                   |
+---------------------------------------------+
| 99                                          |
+---------------------------------------------+

column->path
JSON_EXTRACT()的别名,两个参数分别是左侧的列标识符和右侧的JSON路径,返回的结果中包含转义字符\以及周围的引号保持数据的完整。支持MySQL 5.7.9及更高版本

mysql> SELECT col->"$.mascot" FROM qtest;
+---------------------------------------------+
| col->"$.mascot"                             |
+---------------------------------------------+
| "Our mascot is a dolphin named \"Sakila\"." |
+---------------------------------------------+

mysql> SELECT c, JSON_EXTRACT(c, "$.id"), g
     > FROM jemp
     > WHERE JSON_EXTRACT(c, "$.id") > 1
     > ORDER BY JSON_EXTRACT(c, "$.name");
+-------------------------------+-----------+------+
| c                             | c->"$.id" | g    |
+-------------------------------+-----------+------+
| {"id": "3", "name": "Barney"} | "3"       |    3 |
| {"id": "4", "name": "Betty"}  | "4"       |    4 |
| {"id": "2", "name": "Wilma"}  | "2"       |    2 |
+-------------------------------+-----------+------+

column->>path
查询指定列的指定键的值,类似于JSON_UNQUOTE(JSON_EXTRACT(column, path)),不包括字符周围的引号及转义字符\,支持MySQL 5.7.13和更高版本

mysql> SELECT sentence->>"$.mascot" FROM facts;
+-----------------------------------------+
| sentence->>"$.mascot"                   |
+-----------------------------------------+
| Our mascot is a dolphin named "Sakila". |
+-----------------------------------------+

 

{/if}