zoukankan      html  css  js  c++  java
  • 【MySQL】JSON相关

    一些概念

    MySQL里的json分为json array和json object。

    $表示整个json对象,在索引数据时用下标(对于json array,从0开始)或键值(对于json object,含有特殊字符的key要用"括起来,比如$."my name")。

    JSON_ARRAY函数 ,返回一个JSON数组,参数支持各种类型

    mysql> SELECT JSON_ARRAY(1376, '字符', NULL, FALSE, NOW());
    +-----------------------------------------------------------+
    | JSON_ARRAY(1376, '字符', NULL, FALSE, NOW())              |
    +-----------------------------------------------------------+
    | [1376, "字符", null, false, "2021-07-09 10:47:33.000000"] |
    +-----------------------------------------------------------+
    1 row in set (0.03 sec)
    
    mysql> 

    JSON_OBJECT函数,返回一个JSON对象,要求KV参数必须成双入参

    mysql> SELECT JSON_OBJECT('name', '张三', 'gender', TRUE, 'age', 24);
    +--------------------------------------------------------+
    | JSON_OBJECT('name', '张三', 'gender', TRUE, 'age', 24) |
    +--------------------------------------------------------+
    | {"age": 24, "name": "张三", "gender": true}            |
    +--------------------------------------------------------+
    1 row in set (0.03 sec)
    
    mysql> 

    JSON_QUOTE函数,追加双引号修饰

    JSON_QUOTE(json_val)

    案例

    mysql> SELECT JSON_QUOTE('12321'), JSON_QUOTE('"12321"'), '12321',JSON_QUOTE('[1, 2, 3]');
    +---------------------+-----------------------+-------+-------------------------+
    | JSON_QUOTE('12321') | JSON_QUOTE('"12321"') | 12321 | JSON_QUOTE('[1, 2, 3]') |
    +---------------------+-----------------------+-------+-------------------------+
    | "12321"             | ""12321""           | 12321 | "[1, 2, 3]"             |
    +---------------------+-----------------------+-------+-------------------------+
    1 row in set (0.02 sec)
    
    mysql> 

    JSON_UNQUOTE函数,移除双引号修饰

    JSON_QUOTE(json_val)

     去掉val的引号。如果val为NULL,则返回NULL。

    mysql> SET @j = '"abc"';
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> SELECT @j, JSON_UNQUOTE(@j);
    +-------+------------------+
    | @j    | JSON_UNQUOTE(@j) |
    +-------+------------------+
    | "abc" | abc              |
    +-------+------------------+
    1 row in set (0.01 sec)
    
    mysql> SET @j = '[1, 2, 3]';
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> SELECT @j, JSON_UNQUOTE(@j);
    +-----------+------------------+
    | @j        | JSON_UNQUOTE(@j) |
    +-----------+------------------+
    | [1, 2, 3] | [1, 2, 3]        |
    +-----------+------------------+
    1 row in set (0.02 sec)
    
    mysql> 

    CONVERT函数,将JSON字符串转换为JSON

    CONVERT(json_string,JSON)

    案例

    mysql> SELECT CONVERT('{"NAME": "MIKE", "AGE": 29, "GENDER": true}', JSON);
    +--------------------------------------------------------------+
    | CONVERT('{"NAME": "MIKE", "AGE": 29, "GENDER": true}', JSON) |
    +--------------------------------------------------------------+
    | {"AGE": 29, "NAME": "MIKE", "GENDER": true}                  |
    +--------------------------------------------------------------+
    1 row in set (0.02 sec)
    
    mysql> 

    JSON_CONTAINS函数

    JSON_CONTAINS(json_doc, val[, path])

    查询json文档是否在指定path包含指定的数据,包含则返回1,否则返回0。

    如果有参数为NULL或path不存在,则返回NULL。

    -- 声明一个JSON字符串 
    SET @j = '{"a": 1, "b": 2, "c": {"d": 4}}';
    -- 声明一个1的变量
    SET @j2 = '1';
    -- 查询JSON是否包含参数值函数(参数1 JSON字符串, 参数2 Value值, 参数3 Key值[语法格式:'$.keyname'])
    SELECT JSON_CONTAINS(@j, @j2, '$.a'); -- 查询的是JSON对象的a属性,a属性的值是1,符合函数的包含条件,所以返回1表示结果TRUE
    SELECT JSON_CONTAINS(@j, @j2, '$.b'); -- 查询的是JSON对象的b属性,a属性的值是2,不符合函数包含条件,所以返回0表示结果FALSE

    结果:

    +-------------------------------+
    | JSON_CONTAINS(@j, @j2, '$.a') |
    +-------------------------------+
    |                             1 |
    +-------------------------------+
    1 row in set (0.06 sec)
    
    +-------------------------------+
    | JSON_CONTAINS(@j, @j2, '$.b') |
    +-------------------------------+
    |                             0 |
    +-------------------------------+
    1 row in set (0.05 sec)

    JSON_CONTAINS_PATH函数,查询是否存在一个或多个K键

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

    查询是否存在指定路径,存在则返回1,否则返回0。如果有参数为NULL,则返回NULL。

    one_or_all只能取值"one"或"all",one表示只要有一个存在即可;all表示所有的都存在才行。

    --  定义一个JSON字符串
    SET @j = '{"a": 1, "b": 2, "c": {"d": 4}}';
    
    -- 查询是否包含a键和e键,只要存在其中一个就返回1表示结果TRUE
    SELECT JSON_CONTAINS_PATH(@j, 'one', '$.a', '$.e');
    
    -- 查询是否包含a键和e键,必须全部存在才返回1表示结果TRUE
    SELECT JSON_CONTAINS_PATH(@j, 'all', '$.a', '$.e');
    
    -- 查询是否包含c键下面的d键,只要存在其中一个就返回1表示结果TRUE
    SELECT JSON_CONTAINS_PATH(@j, 'one', '$.c.d');
    
    -- 查询是否包含a键下面的d键,只要存在其中一个就返回1表示结果TRUE
    SELECT JSON_CONTAINS_PATH(@j, 'one', '$.a.d');

    JSON_EXTRACT抽取JSON数据

    JSON_EXTRACT(json_doc, path[, path] ...)

    从json文档里抽取数据。如果有参数有NULL或path不存在,则返回NULL。

    如果抽取出多个path,则返回的数据封闭在一个json array里。

    -- 抽取参数一的JSON数组,取值是数组的索引1
    SELECT JSON_EXTRACT('[10, 20, [30, 40]]', '$[1]');
    
    -- 抽取多个,且合并成数组返回
    SELECT JSON_EXTRACT('[10, 20, [30, 40]]', '$[1]', '$[0]');
    
    -- 抽取索引2的全部元素
    SELECT JSON_EXTRACT('[10, 20, [30, 40]]', '$[2][*]');

    在MySQL5.7.9版本中,支持使用【->】代替JSON_EXRACT表示

    在MySQL5.7.13+版本中,支持使用【->>】代替JSON_EXRACT和JSON_UNQUOTE表示

    语法演变:

    JSON_UNQUOTE( JSON_EXTRACT(column, path) )
    JSON_UNQUOTE(column -> path)
    column->>path

    JSON_KEYS 获取指定K键下的所有K值

    JSON_KEYS(json_doc[, path])

    获取json文档在指定路径下的所有键值,返回一个json array。

    如果有参数为NULL或path不存在,则返回NULL。

    -- 直接对这个JSON对象获取所有K键【无论是一个还是多个,返回的都是JSON数组】
    SELECT JSON_KEYS('{"a": 1, "b": {"c": 30}}');
    
    -- 获取B键下的C键
    SELECT JSON_KEYS('{"a": 1, "b": {"c": 30}}', '$.b');

    JSON_SEARCH 查询K键的索引

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

    查询包含指定字符串的paths,并作为一个json array返回。

    如果有参数为NUL或path不存在,则返回NULL。

    one_or_all:"one"表示查询到一个即返回;"all"表示查询所有。

    search_str:要查询的字符串。 可以用LIKE里的'%'或‘_’匹配。

    path:在指定path下查。

    -- 声明一个JSON数组
    SET @j = '["abc", [{"k": "10"}, "def"], {"x":"abc"}, {"y":"bcd"}]';
    
    -- 查询字符串‘abc’是否存在,如果不存在返回NULL,存在则返回所在的索引位置或者是K键名称,参数'one'表示查找第一个立刻返回(忽略后面相同的)
    SELECT JSON_SEARCH(@j, 'one', 'abc');
    
    -- 查询字符串‘abc’是否存在,如果不存在返回NULL,存在则返回所在的索引位置或者是K键名称,参数'all'表示查找JSON对象中所有的
    SELECT JSON_SEARCH(@j, 'all', 'abc');

    JSON_APPEND/JSON_ARRAY_APPEND

    JSON_ARRAY_APPEND(json_doc, path, val[, path, val] ...)

    在指定path的json array尾部追加val。

    如果指定path是一个json object,则将其封装成一个json array再追加。

    如果有参数为NULL,则返回NULL。

    -- 设置JSON数组
    SET @j = '["a", ["b", "c"], "d"]';
    
    -- 对JSON数组的索引1的元素追加值1
    SELECT JSON_ARRAY_APPEND(@j, '$[1]', 1);
    
    -- 对JSON数组的索引0的元素追加值2
    SELECT JSON_ARRAY_APPEND(@j, '$[0]', 2);
    
    -- 对JSON数组的索引1下的元素索引0追加值3
    SELECT JSON_ARRAY_APPEND(@j, '$[1][0]', 3);

    命令行执行效果:

        -> SET @j = '["a", ["b", "c"], "d"]';
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> SELECT JSON_ARRAY_APPEND(@j, '$[1]', 1);
    +----------------------------------+
    | JSON_ARRAY_APPEND(@j, '$[1]', 1) |
    +----------------------------------+
    | ["a", ["b", "c", 1], "d"]        |
    +----------------------------------+
    1 row in set (0.02 sec)
    
    mysql> SELECT JSON_ARRAY_APPEND(@j, '$[0]', 2);
    +----------------------------------+
    | JSON_ARRAY_APPEND(@j, '$[0]', 2) |
    +----------------------------------+
    | [["a", 2], ["b", "c"], "d"]      |
    +----------------------------------+
    1 row in set (0.02 sec)
    
    mysql> SELECT JSON_ARRAY_APPEND(@j, '$[1][0]', 3);
    +-------------------------------------+
    | JSON_ARRAY_APPEND(@j, '$[1][0]', 3) |
    +-------------------------------------+
    | ["a", [["b", 3], "c"], "d"]         |
    +-------------------------------------+
    1 row in set (0.03 sec)
    
    mysql>

    JSON_ARRAY_INSERT

    JSON_ARRAY_INSERT(json_doc, path, val[, path, val] ...)

    在path指定的json array元素插入val,原位置及以右的元素顺次右移。

    如果path指定的数据非json array元素,则略过此val;

    如果指定的元素下标超过json array的长度,则插入尾部。

    -- 设置JSON数组
    SET @j = '["a", {"b": [1, 2]}, [3, 4]]';
    
    -- 向索引1的位置上插入元素'x', 原先索引1及其后面的元素都会被后置
    SELECT JSON_ARRAY_INSERT(@j, '$[1]', 'x');
    
    -- 在索引100的位置上插入元素'x',实际上JSON数组长度不够100,则直接在最后处插入'x'元素
    SELECT JSON_ARRAY_INSERT(@j, '$[100]', 'x');
    
    -- 索引1的元素是JSON对象,b属性又是一个JSON数组,在这个B属性索引0上插入'x'元素
    SELECT JSON_ARRAY_INSERT(@j, '$[1].b[0]', 'x');
    
    -- 数组下的索引2数组,索引1插入元素'x'
    SELECT JSON_ARRAY_INSERT(@j, '$[2][1]', 'y');
    
    -- 插入两个元素,并设置了不同位置
    SELECT JSON_ARRAY_INSERT(@j, '$[0]', 'x', '$[2][1]', 'y');

    命令行效果:

    mysql> SET @j = '["a", {"b": [1, 2]}, [3, 4]]';
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> SELECT JSON_ARRAY_INSERT(@j, '$[1]', 'x');
    +------------------------------------+
    | JSON_ARRAY_INSERT(@j, '$[1]', 'x') |
    +------------------------------------+
    | ["a", "x", {"b": [1, 2]}, [3, 4]]  |
    +------------------------------------+
    1 row in set (0.02 sec)
    
    mysql> SELECT JSON_ARRAY_INSERT(@j, '$[100]', 'x');
    +--------------------------------------+
    | JSON_ARRAY_INSERT(@j, '$[100]', 'x') |
    +--------------------------------------+
    | ["a", {"b": [1, 2]}, [3, 4], "x"]    |
    +--------------------------------------+
    1 row in set (0.02 sec)
    
    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]]       |
    +-----------------------------------------+
    1 row in set (0.02 sec)
    
    mysql> SELECT JSON_ARRAY_INSERT(@j, '$[2][1]', 'y');
    +---------------------------------------+
    | JSON_ARRAY_INSERT(@j, '$[2][1]', 'y') |
    +---------------------------------------+
    | ["a", {"b": [1, 2]}, [3, "y", 4]]     |
    +---------------------------------------+
    1 row in set (0.03 sec)
    
    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]]                  |
    +----------------------------------------------------+
    1 row in set (0.03 sec)
    
    mysql> 

    JSON_INSERT/JSON_REPLACE/JSON_SET

    插入数据

    JSON_INSERT(json_doc, path, val[, path, val] ...)

    在指定path下插入数据,如果path已存在,则忽略此val(不存在才插入)。

    mysql> SET @j = '{ "a": 1, "b": [2, 3]}';
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> SELECT JSON_INSERT(@j, '$.a', 10, '$.c', '[true, false]');
    +----------------------------------------------------+
    | JSON_INSERT(@j, '$.a', 10, '$.c', '[true, false]') |
    +----------------------------------------------------+
    | {"a": 1, "b": [2, 3], "c": "[true, false]"}        |
    +----------------------------------------------------+
    1 row in set (0.02 sec)
    
    mysql> 

    替换数据

    JSON_REPLACE(json_doc, path, val[, path, val] ...)

    替换指定路径的数据,如果某个路径不存在则略过(存在才替换)。

    如果有参数为NULL,则返回NULL。

    mysql> SET @j = '{ "a": 1, "b": [2, 3]}';
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> SELECT JSON_REPLACE(@j, '$.a', 10, '$.c', '[true, false]');
    +-----------------------------------------------------+
    | JSON_REPLACE(@j, '$.a', 10, '$.c', '[true, false]') |
    +-----------------------------------------------------+
    | {"a": 10, "b": [2, 3]}                              |
    +-----------------------------------------------------+
    1 row in set (0.01 sec)
    
    mysql> 

    设置指定的数据:

    JSON_SET(json_doc, path, val[, path, val] ...)

    设置指定路径的数据(不管是否存在)。如果有参数为NULL,则返回NULL。

    mysql> SET @j = '{ "a": 1, "b": [2, 3]}';
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> SELECT JSON_SET(@j, '$.a', 10, '$.c', '[true, false]');
    +-------------------------------------------------+
    | JSON_SET(@j, '$.a', 10, '$.c', '[true, false]') |
    +-------------------------------------------------+
    | {"a": 10, "b": [2, 3], "c": "[true, false]"}    |
    +-------------------------------------------------+
    1 row in set (0.01 sec)
    
    mysql> SELECT JSON_INSERT(@j, '$.a', 10, '$.c', '[true, false]');
    +----------------------------------------------------+
    | JSON_INSERT(@j, '$.a', 10, '$.c', '[true, false]') |
    +----------------------------------------------------+
    | {"a": 1, "b": [2, 3], "c": "[true, false]"}        |
    +----------------------------------------------------+
    1 row in set (0.02 sec)
    
    mysql> SELECT JSON_REPLACE(@j, '$.a', 10, '$.c', '[true, false]');
    +-----------------------------------------------------+
    | JSON_REPLACE(@j, '$.a', 10, '$.c', '[true, false]') |
    +-----------------------------------------------------+
    | {"a": 10, "b": [2, 3]}                              |
    +-----------------------------------------------------+
    1 row in set (0.03 sec)
    
    mysql> 

    JSON_MERGE

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

    merge多个json文档。规则如下:

    • 如果都是json array,则结果自动merge为一个json array;
    • 如果都是json object,则结果自动merge为一个json object;
    • 如果有多种类型,则将非json array的元素封装成json array再按照规则一进行mege。
    mysql> SELECT JSON_MERGE('[1, 2]', '[true, false]');
    +---------------------------------------+
    | JSON_MERGE('[1, 2]', '[true, false]') |
    +---------------------------------------+
    | [1, 2, true, false]                   |
    +---------------------------------------+
    1 row in set (0.02 sec)
    
    mysql> SELECT JSON_MERGE('{"name": "x"}', '{"id": 47}');
    +-------------------------------------------+
    | JSON_MERGE('{"name": "x"}', '{"id": 47}') |
    +-------------------------------------------+
    | {"id": 47, "name": "x"}                   |
    +-------------------------------------------+
    1 row in set (0.02 sec)
    
    mysql> SELECT JSON_MERGE('1', 'true');
    +-------------------------+
    | JSON_MERGE('1', 'true') |
    +-------------------------+
    | [1, true]               |
    +-------------------------+
    1 row in set (0.02 sec)
    
    mysql> SELECT JSON_MERGE('[1, 2]', '{"id": 47}');
    +------------------------------------+
    | JSON_MERGE('[1, 2]', '{"id": 47}') |
    +------------------------------------+
    | [1, 2, {"id": 47}]                 |
    +------------------------------------+
    1 row in set (0.02 sec)
    
    mysql> 

    JSON_REMOVE

    移除数据

    JSON_REMOVE(json_doc, path[, path] ...)

    移除指定路径的数据,如果某个路径不存在则略过此路径。如果有参数为NULL,则返回NULL。

    mysql> SET @j = '["a", ["b", "c"], "d"]';
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> SELECT JSON_REMOVE(@j, '$[1]');
    +-------------------------+
    | JSON_REMOVE(@j, '$[1]') |
    +-------------------------+
    | ["a", "d"]              |
    +-------------------------+
    1 row in set (0.01 sec)
    
    mysql> 

    JSON_DEEPTH

    查询JSON文档的深度

    JSON_DEPTH(json_doc)

    获取json文档的深度。如果参数为NULL,则返回NULL。

    空的json array、json object或标量的深度为1。

    mysql> SELECT JSON_DEPTH('{}'), JSON_DEPTH('[]'), JSON_DEPTH('true');
    +------------------+------------------+--------------------+
    | JSON_DEPTH('{}') | JSON_DEPTH('[]') | JSON_DEPTH('true') |
    +------------------+------------------+--------------------+
    |                1 |                1 |                  1 |
    +------------------+------------------+--------------------+
    1 row in set (0.01 sec)
    
    mysql> SELECT JSON_DEPTH('[10, 20]'), JSON_DEPTH('[[], {}]');
    +------------------------+------------------------+
    | JSON_DEPTH('[10, 20]') | JSON_DEPTH('[[], {}]') |
    +------------------------+------------------------+
    |                      2 |                      2 |
    +------------------------+------------------------+
    1 row in set (0.02 sec)
    
    mysql> SELECT JSON_DEPTH('[10, {"a": 20}]');
    +-------------------------------+
    | JSON_DEPTH('[10, {"a": 20}]') |
    +-------------------------------+
    |                             3 |
    +-------------------------------+
    1 row in set (0.02 sec)
    
    mysql> 

    JSON_LENGTH

    JSON_LENGTH(json_doc[, path])

    获取指定路径下的长度。如果参数为NULL,则返回NULL。

    长度的计算规则:

    • 标量的长度为1;
    • json array的长度为元素的个数;
    • json object的长度为key的个数。
    mysql> SELECT JSON_LENGTH('[1, 2, {"a": 3}]');
    +---------------------------------+
    | JSON_LENGTH('[1, 2, {"a": 3}]') |
    +---------------------------------+
    |                               3 |
    +---------------------------------+
    1 row in set (0.02 sec)
    
    mysql> SELECT JSON_LENGTH('{"a": 1, "b": {"c": 30}}');
    +-----------------------------------------+
    | JSON_LENGTH('{"a": 1, "b": {"c": 30}}') |
    +-----------------------------------------+
    |                                       2 |
    +-----------------------------------------+
    1 row in set (0.02 sec)
    
    mysql> SELECT JSON_LENGTH('{"a": 1, "b": {"c": 30}}', '$.b');
    +------------------------------------------------+
    | JSON_LENGTH('{"a": 1, "b": {"c": 30}}', '$.b') |
    +------------------------------------------------+
    |                                              1 |
    +------------------------------------------------+
    1 row in set (0.03 sec)
    
    mysql> 

     

    JSON_TYPE

    JSON_TYPE(json_val)

    获取json文档的具体类型。如果参数为NULL,则返回NULL。

    https://www.cnblogs.com/waterystone/p/5626098.html

    json中的数据可以用 =, <, <=, >, >=, <>, !=, and <=> 进行比较。

    但json里的数据类型可以是多样的,那么在不同类型之间进行比较时,就有优先级了,高优先级的要大于低优先级的(可以用JSON_TYPE()函数查看类型)。

    优先级从高到低如下:

    BLOB
    BIT
    OPAQUE
    DATETIME
    TIME
    DATE
    BOOLEAN
    ARRAY
    OBJECT
    STRING
    INTEGER, DOUBLE
    NULL

    JSON_VALID

    JSON_VALID(val)

    判断val是否为有效的json格式,是为1,不是为0。

    如果参数为NUL,则返回NULL。

    mysql> SELECT JSON_VALID('{"a": 1}');
    +------------------------+
    | JSON_VALID('{"a": 1}') |
    +------------------------+
    |                      1 |
    +------------------------+
    1 row in set (0.02 sec)
    
    mysql> SELECT JSON_VALID('hello'), JSON_VALID('"hello"');
    +---------------------+-----------------------+
    | JSON_VALID('hello') | JSON_VALID('"hello"') |
    +---------------------+-----------------------+
    |                   0 |                     1 |
    +---------------------+-----------------------+
    1 row in set (0.02 sec)
    
    mysql> 
  • 相关阅读:
    weekly review 200812: Tire
    monthly report 200802: between the festival and the happiness
    weekly review 200813: Ill
    Android中的SharedPreferences
    如何使用Github上的开源项目
    Android四大组件
    开发者需知的10类工具
    activity中onResume()的用处
    Redhat 5.4 + ASM + RAW+ Oracle 10g RAC 安装文档
    Oracle 索引扫描的五种类型
  • 原文地址:https://www.cnblogs.com/mindzone/p/14989866.html
Copyright © 2011-2022 走看看