本文搬运了MySQL对JSON的支持相关的函数
/* 自MySQL 5.7版本以后,加入了JSON字段类型支持,并提供一系列函数
实测字段类型设置为varchar,只要字段值为合法json,MYSQL JSON对应的函数都可以使用
*/
-- 1 返回一个JSON数组
SELECT JSON_ARRAY(1, "abc", NULL, TRUE, CURTIME());
-- 2 返回一个JSON对象
SELECT JSON_OBJECT('id', 87, 'name', 'carrot');
-- 3 转义
SELECT JSON_QUOTE('null'), JSON_QUOTE('"null"'), JSON_QUOTE(null), JSON_quote('{"name":"zhangsan","age":44}');
-- **4 返回目标JSON中是否包含查询的值,结果为0/1
-- JSON_CONTAINS(target, candidate[, path])
SELECt json_contains(json_address, JSON_QUOTE('西安'), '$.city') from test;
-- SELECT JSON_CONTAINS(string_address, JSON_QUOTE('西安'), '$.city') FROM test;
-- 错误写法,第二个参数需要用JSON_QUOTE进行转义,并且只支持精确查找
-- SELECT JSON_CONTAINS(json_address, '西安', '$.city') FROM test;
-- 5 检查目标JSON中是否包含对应路径
-- JSON_CONTAINS_PATH(json_doc, one_or_all, path[, path] ...)
SELECT JSON_CONTAINS_PATH(json_address, 'one', '$.province', '$.name') FROM test;
SELECT JSON_CONTAINS_PATH(json_address, 'all', '$.province', '$.name') FROM test;
-- **6 返回一个JSON文档的属性值,返回值包含双引号
-- JSON_EXTRACT(json_doc, path[, path] ...)
SELECT json_address->'$.province' FROM test;
SELECT JSON_EXTRACT(json_address, '$.province') FROM test;
SELECT JSON_EXTRACT('[10, 20, [30, 40]]', '$[1]');
SELECT JSON_EXTRACT('[10, 20, [30, 40]]', '$[1]', '$[0]');
SELECT JSON_EXTRACT('[10, 20, [30, 40]]', '$[2][*]');
SELECT JSON_EXTRACT('[10, 20, [30, 40]]', '$[2][1]');
-- **6.1 查询JSON的某个属性,返回值不包含双引号
SELECT json_address->>'$.province' FROM test;
SELECT JSON_UNQUOTE(JSON_EXTRACT(json_address, '$.province')) FROM test;
-- column->path 可以按照属性值进行查询,分组,排序等操作
SELECT json_address,json_extract(json_address, '$.province') from test where json_extract(json_address, '$.city') = '西安';
SELECT json_address->'$.province' FROM test WHERE json_address->'$.province' = '河南';
SELECT json_address->>'$.province' FROM test WHERE json_address->>'$.province' = '河南';
-- 7 返回JSON文档的顶层值的key(支持嵌套),该函数要求目标字段值为一个合法的JSON,否则会抛出错误
-- JSON_KEYS(json_doc[, path])
SELECT JSON_KEYS(json_address) FROM test;
SELECT JSON_KEYS(json_address, '$.attr') FROM test;
-- 8 对比两个JSON: 比较两个JSON文档。如果两个文档有任何共同的键值对或数组元素,则返回true (1)。如果两个参数都是标量,则函数执行简单的相等性测试。如果任一参数为NULL,则函数返回NULL。
-- JSON_OVERLAPS(json_doc1, json_doc2)
-- SINCE MySQL 8.0.17
SELECT JSON_OVERLAPS(json_address, string_address) FROM test;
-- 9 返回JSON文档中给定字符串的路径,支持模糊匹配
-- JSON_SEARCH(json_doc, one_or_all, search_str[, escape_char[, path] ...])
SELECT json_search(json_address, 'one', '陕西') FROM test;
SELECT json_search(json_address, 'one', '%西%') FROM test;
SELECT json_search(json_address, 'all', '%西%') FROM test;
-- 10 从指定文档中给定的路径处的JSON文档中提取值,并返回提取的值,可选地将其转换为所需的类型
-- JSON_VALUE(json_doc, path)
SELECT json_value(json_address, '$.province') FROM test;
SELECT json_value(json_address, '$.number' RETURNING DECIMAL(6,2)) FROM test;
-- 11 如果value是json_array的元素,则返回true (1),否则返回false (0)。值必须是标量或JSON文档; 如果它是标量,则运算符尝试将其视为JSON数组的元素。如果value或json_array为NULL,则函数返回NULL。
-- value MEMBER OF(json_array)
SELECT 'ab' MEMBER OF('[23, "abc", 17, "ab", 10]');
SELECT 'a' MEMBER OF('[23, "abc", 17, "ab", 10]');
SELECT JSON_ARRAY(4,5) MEMBER OF('[[3,4],[4,5]]');
-- 12 将值附加到JSON文档中指示的数组的末尾,并返回结果。如果任何参数为NULL,则返回NULL。如果json_doc参数不是有效的JSON文档,或者任何path参数不是有效的路径表达式,或者包含 * 或 ** 通配符,则会发生错误。
-- JSON_ARRAY_APPEND(json_doc, path, val[, path, val] ...)
-- 在MySQL 5.7中,这个函数被命名为JSON_APPEND()。MySQL 8.0中不再支持该名称。
SELECT JSON_ARRAY_APPEND('["a", ["b", "c"], "d"]', '$[1]', 1);
-- 13 更新JSON文档,插入到文档中的数组中,然后返回修改后的文档。
-- JSON_ARRAY_INSERT(json_doc, path, val[, path, val] ...)
SELECT JSON_ARRAY_INSERT('["a", ["b", "c"], "d"]', '$[1]', 1);
-- 14 将数据插入到JSON文档中并返回结果。如果对应的路径已存在,不会更新对应的值
-- JSON_INSERT(json_doc, path, val[, path, val] ...)
SELECT JSON_INSERT(json_address, '$.province', '江西') FROM test WHERE id = 1;
SELECT JSON_INSERT(json_address, '$.test', 'home') FROM test WHERE id = 1;
-- 15 合并两个json文档
-- JSON_MERGE(json_doc, json_doc[, json_doc] ...) 后续可能会弃用
-- JSON_MERGE_PRESERVE(json_doc, json_doc[, json_doc] ...) -- 相同键名时,进行了合并
-- JSON_MERGE_PATCH(json_doc, json_doc[, json_doc] ...) -- 相同键名时,后面参数覆盖前面参数
SELECT JSON_MERGE('[1, 2]', '[true, false]');
SET @x = '{ "a": 1, "b": 2 }',
@y = '{ "a": 3, "c": 4 }',
@z = '{ "a": 5, "d": 6 }';
SELECT JSON_MERGE_PATCH(@x, @y, @z) AS Patch,
JSON_MERGE_PRESERVE(@x, @y, @z) AS Preserve/G;
-- 16 从JSON文档中删除数据并返回结果
-- JSON_REMOVE(json_doc, path[, path] ...)
SELECT JSON_REMOVE(json_address, '$.province') FROM test WHERE id = 1;
-- **17 插入,更新,替换JSON文档中的值
-- JSON_SET() 替换现有值并添加不存在的值。
-- JSON_INSERT() 在不替换现有值的情况下插入值。
-- JSON_REPLACE() 仅替换现有值。
-- 18 返回JSON文档的最大深度
-- JSON_DEPTH(json_doc)
-- 19 返回JSON文档的长度
-- JSON_DEPTH(json_doc)
-- 20 判断JSON值的类型,可能为object,array,或者标量
-- JSON_TYPE(json_val)
-- **21 返回0或1以指示值是否为有效JSON。
-- JSON_VALID(val)
-- 22 从JSON文档中提取数据,并将其作为具有指定列的关系表返回。
-- JSON_TABLE(expr, path COLUMNS (column_list) [AS] alias)
SELECT
*
FROM
JSON_TABLE (
'[{"a":"3"},{"a":2},{"b":1},{"a":0},{"a":[1,2]}]',
"$[*]" COLUMNS (
rowid FOR ORDINALITY,
ac VARCHAR (100) PATH "$.a" DEFAULT '111'
ON EMPTY DEFAULT '999'
ON ERROR,
aj JSON PATH "$.a" DEFAULT '{"x": 333}'
ON EMPTY,
bx INT EXISTS PATH "$.b"
)
) AS tt;
-- 23 根据JSON规范对JSON文档进行验证
-- JSON_SCHEMA_VALID(schema,document)
SET @schema = '{
"id": "http://json-schema.org/geo",
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "A geographical coordinate",
"type": "object",
"properties": {
"latitude": {
"type": "number",
"minimum": -90,
"maximum": 90
},
"longitude": {
"type": "number",
"minimum": -180,
"maximum": 180
}
}
}';
SELECT
JSON_SCHEMA_VALID (
@schema,
'{
"latitude": 263.444697,
"longitude": 10.445118
}'
);
-- 24 JSON工具函数
-- 24.1 JSON美化输出
SELECT json_pretty(json_address) FROM test WHERE id = 1;
-- 24.2 计算使用JSON_SET,JSON_REPLACE,JSON_REMOVE更新JSON字段后,释放的二进制字节数
-- JSON_STORAGE_FREE(json_val)
-- 24.3 该函数返回用于存储JSON文档的二进制表示形式的字节数
-- JSON_STORAGE_SIZE(json_val)
SELECT json_storage_size(json_address) FROM test WHERE id = 1;
附官方文档地址:https://dev.mysql.com/doc/refman/8.0/en/json-functions.html
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/281349.html