mysql解析json字符串,字符串查找,子串截取和字段类型转换相关总结

mysql解析json字符串,字符串查找,子串截取和字段类型转换相关总结

很多时候,我们需要在sql里面直接解析json字符串。这里针对mysql5.7版本的分水岭进行区分。

1.对于mysql5.7以上版本

    使用mysql的内置函数JSON_EXTRACT(column, '$.key'),这个函数有两个参数,第一个参数column代表json列的列名;第二个参数key代表json字符串中的某一个key。

    SELECT JSON_EXTRACT('{"priceTag":"员工/合作关键人","priceDiscount":"90"}', '$.priceDiscount') AS '定价折扣';

    对于简单的json字符串肯定是可以解析成功,但是对于嵌套数组的没试过。

2.对于mysql5.7以下版本

    只能充分发挥已有函数的功能去截取实现,无论实现方式是存储过程还是简单的sql语句,其原理都是一样的。

    第一步,将所有的花括号的闭括号'}'替换成英文逗号',';第二步,获取key的坐标keyIndex和长度keyLength;第三步,获取以key为起点,第一个英文逗号','的坐标symbolIndex;第四步,使用substring截取字符串SUBSTRING(targetJsonStr, keyIndex + keyLength, symbolIndex - keyIndex - keyLength);第五步,使用replace将双引号'"'替换成空字符串'',完工。

    示例:从{"priceTag": "员工/合作关键人","priceDiscount": "90"}中获取priceDiscount的值。

SELECT
    REPLACE(
        SUBSTRING(
            REPLACE(
                '{"priceTag":"员工/合作关键人","priceDiscount":"90"}' ,
                '}' ,
                ','
            ) ,
            LOCATE(
                'priceDiscount":' ,
                REPLACE(
                    '{"priceTag":"员工/合作关键人","priceDiscount":"90"}' ,
                    '}' ,
                    ','
                )
            ) + CHAR_LENGTH('priceDiscount":') ,
            LOCATE(
                ',' ,
                REPLACE(
                    '{"priceTag":"员工/合作关键人","priceDiscount":"90"}' ,
                    '}' ,
                    ','
                ) ,
                LOCATE(
                    'priceDiscount":' ,
                    REPLACE(
                        '{"priceTag":"员工/合作关键人","priceDiscount":"90"}' ,
                        '}' ,
                        ','
                    )
                ) + CHAR_LENGTH('priceDiscount":')
            ) -(
                LOCATE(
                    'priceDiscount":' ,
                    REPLACE(
                        '{"priceTag":"员工/合作关键人","priceDiscount":"90"}' ,
                        '}' ,
                        ','
                    )
                ) + CHAR_LENGTH('priceDiscount":')
            )
        ) ,
        '"' ,
        ''
    ) AS '定价折扣';

参考:https://www.jianshu.com/p/513acedf436d

3、 其他相关函数如下:

方法罗列:

分类 函数 描述

创建json

json_array 创建json数组

json_object 创建json对象

json_quote 将json转成json字符串类型

查询json 

json_contains 判断是否包含某个json值

json_contains_path 判断某个路径下是否包json值

json_extract 提取json值

column->path json_extract的简洁写法,MySQL 5.7.9开始支持

column->>path json_unquote(column -> path)的简洁写法

json_keys 提取json中的键值为json数组

json_search 按给定字符串关键字搜索json,返回匹配的路径

修改json 

json_append 废弃,MySQL 5.7.9开始改名为json_array_append

json_array_append 末尾添加数组元素,如果原有值是数值或json对 象,则转成数组后,再添加元素

json_array_insert 插入数组元素

json_insert 插入值(插入新值,但不替换已经存在的旧值)

json_merge 合并json数组或对象

json_remove 删除json数据

json_replace 替换值(只替换已经存在的旧值)

json_set 设置值(替换旧值,并插入不存在的新值)

json_unquote 去除json字符串的引号,将值转成string类型

返回json属性 

json_depth 返回json文档的最大深度

json_length 返回json文档的长度

json_type 返回json值得类型

json_valid 判断是否为合法json文档

参考:https://blog.csdn.net/jiangyu1013/article/details/78917425

4、我的例子:

table tb_evaluate_class:有一个字段如下:

`live_system_shortphrases` varchar(500) NOT NULL DEFAULT '' COMMENT '评价系统快捷短语'

mysql> select live_system_shortphrases from tb_evaluate_class limit 2;

+---------------------------------------------------------------------+

| live_system_shortphrases |

+---------------------------------------------------------------------+

| {"content":["\u5361\u987f\u9ed1\u5c4f","\u58f0\u97f3\u5f02\u5e38"]} |

| {"content":[]} |

+---------------------------------------------------------------------+

2 rows in set (0.00 sec)

 

mysql> select '声音异常' as exception_name,case when locate('声音异常',JSON_EXTRACT(live_system_shortphrases,'$.content')) >0 then 1 else 0 end num from tb_evaluate_class;

ERROR 3141 (22032): Unknown error 3141

相关原因分析:

mysql> SELECT CAST('NULL' AS JSON); ERROR 3141 (22032): Invalid JSON text in argument 1 to function cast_as_json: "Invalid value." at position 0 in 'NULL'.

mysql> SELECT CAST('' AS JSON);

ERROR 3141 (22032): Invalid JSON text in argument 1 to function cast_as_json: "The document is empty." at position 0 in ''.

mysql> SELECT CAST('{]' AS JSON);

ERROR 3141 (22032): Invalid JSON text in argument 1 to function cast_as_json: "Missing a name for object member." at position 1 in '{]'.

Note that many keywords that might be valid in other environments, like NaN, Infinity, javascript built-in constructor fields like Number.

解决办法,去出长度为0的字符串即可:

mysql> select '声音异常' as exception_name,case when locate('声音异常',JSON_EXTRACT(cast(live_system_shortphrases as json),'$.content')) >0 then 1 else 0 end num from hb_evaluate_class where length(live_system_shortphrases)!=0 limit 3;

+----------------+-----+

| exception_name | num |

+----------------+-----+

| 声音异常 | 1 |

| 声音异常 | 0 |

| 声音异常 | 0 |

+----------------+-----+

3 rows in set (0.00 sec)

参考:https://dev.mysql.com/doc/refman/5.7/en/json.html

5、扩展:Mysql json字符串解析成对应字段

    对于mysql5.7以上版本,使用mysql的内置函数JSON_EXTRACT(column, '$.key'),这个函数有两个参数,第一个参数column代表json列的列名;第二个参数key代表json字符串中的某一个key。

mysql> select live_system_shortphrases from tb_evaluate_class limit 2;

+---------------------------------------------------------------------+

| live_system_shortphrases |

+---------------------------------------------------------------------+

| {"content":["\u5361\u987f\u9ed1\u5c4f","\u58f0\u97f3\u5f02\u5e38"]} |

| {"content":[]} |

+---------------------------------------------------------------------+

2 rows in set (0.01 sec)

mysql> select JSON_EXTRACT(live_system_shortphrases,'$.content') as josn_str from tb_evaluate_class limit 2;

+----------------------------------+

| josn_str |

+----------------------------------+

| ["卡顿黑屏", "声音异常"] |

| [] |

+----------------------------------+

2 rows in set (0.00 sec)

Mysql json字符串进行替换

mysql> select REPLACE(JSON_EXTRACT(live_system_shortphrases,'$.content'),'异常',' exception') as replace_str from tb_evaluate_class limit 2;

+--------------------------------------+

| replace_str |

+--------------------------------------+

| ["卡顿黑屏", "声音 exception"] |

| [] |

+--------------------------------------+

2 rows in set (0.00 sec)

6、MySQL字符查找和截取:

mysql 查找字符串位置 instr()与LOCATE()字符串查找函数

https://blog.csdn.net/weixin_35751376/article/details/60583967

NSTR(str,substr) 

返回字符串 str 中子字符串的第一个出现位置。这和LOCATE()的双参数形式相同,除非参数的顺序被颠倒。

mysql> SELECT INSTR('foobarbar', 'bar');

+---------------------------+

| INSTR('foobarbar', 'bar') |

+---------------------------+

| 4 |

+---------------------------+

1 row in set (0.00 sec)

 

mysql> SELECT INSTR('xbar', 'foobar');

+-------------------------+

| INSTR('xbar', 'foobar') |

+-------------------------+

| 0 |

+-------------------------+

1 row in set (0.00 sec)

mysql> SELECT INSTR('foobarbar', 'BAr');

+---------------------------+

| INSTR('foobarbar', 'BAr') |

+---------------------------+

| 4 |

+---------------------------+

1 row in set (0.00 sec)

 

LOCATE(substr,str) , LOCATE(substr,str,pos) 

第一个语法返回字符串 str中子字符串substr的第一个出现位置。第二个语法返回字符串 str中子字符串substr的第一个出现位置, 起始位置在pos。如若substr 不在str中,则返回值为0。

mysql> SELECT LOCATE('bar', 'foobarbar');

+----------------------------+

| LOCATE('bar', 'foobarbar') |

+----------------------------+

| 4 |

+----------------------------+

1 row in set (0.00 sec)

 

mysql> SELECT LOCATE('xbar', 'foobar');

+--------------------------+

| LOCATE('xbar', 'foobar') |

+--------------------------+

| 0 |

+--------------------------+

1 row in set (0.00 sec)

 

mysql> SELECT LOCATE('bar', 'foobarbar',5);

+------------------------------+

| LOCATE('bar', 'foobarbar',5) |

+------------------------------+

| 7 |

+------------------------------+

1 row in set (0.00 sec)

mysql> SELECT LOCATE('BaR', 'foobarbar',5);

+------------------------------+

| LOCATE('BaR', 'foobarbar',5) |

+------------------------------+

| 7 |

+------------------------------+

1 row in set (0.00 sec)

这个函数支持多字节字元,并且只有当至少有一个参数是二进制字符串时区分大小写。

 

参考:https://www.cnblogs.com/mojiexiaolong/p/6979617.html

mysql 字符串截取函数--substr()

1.用法:

substr(string string,num start,num length);

string为字符串;

start为起始位置;

length为长度。

2.区别:

mysql中的start是从1开始的,而hibernate中的start是从0开始的。

 

mysql> select substr('123456789',1,3);

+-------------------------+

| substr('123456789',1,3) |

+-------------------------+

| 123 |

+-------------------------+

1 row in set (0.00 sec)

 

mysql> select substr('123456789',4,3);

+-------------------------+

| substr('123456789',4,3) |

+-------------------------+

| 456 |

+-------------------------+

1 row in set (0.01 sec)

利用截取的子串和数字比较大小:

mysql> select substr('123456789',4,3)>123;

+-----------------------------+

| substr('123456789',4,3)>123 |

+-----------------------------+

| 1 |

+-----------------------------+

1 row in set (0.00 sec)

 

mysql> select substr('123456789',4,3)>987;

+-----------------------------+

| substr('123456789',4,3)>987 |

+-----------------------------+

| 0 |

+-----------------------------+

1 row in set (0.00 sec)

7、MYSQL中,字段类型转换-CAST函数的使用规则

CAST函数语法规则是:Cast(字段名 as 转换的类型 ),其中类型可以为:

CHAR[(N)] 字符型 

DATE 日期型

DATETIME 日期和时间型

DECIMAL float型

SIGNED int

TIME 时间型

mysql> select cast('2015-11-03 15:31:26' as char) as date;

+---------------------+

| date |

+---------------------+

| 2015-11-03 15:31:26 |

+---------------------+

1 row in set (0.00 sec)

 

mysql> select cast('2015-11-03 15:31:26' as datetime) as date;

+---------------------+

| date |

+---------------------+

| 2015-11-03 15:31:26 |

+---------------------+

1 row in set (0.00 sec)

 

mysql> select cast('2015-11-03 15:31:26' as date) as date;

+------------+

| date |

+------------+

| 2015-11-03 |

+------------+

1 row in set (0.00 sec)

 

mysql> select cast('2015-11-03 15:31:26' as time) as date;

+----------+

| date |

+----------+

| 15:31:26 |

+----------+

1 row in set (0.00 sec)

这里date对应日期,time对应时间

mysql> select cast('30' as decimal(10, 2)) as num;

+-------+

| num |

+-------+

| 30.00 |

+-------+

1 row in set (0.00 sec)

解释:decimal 数据类型最多可存储 38 个数字,所有数字都能够放到小数点的右边.decimal 数据类型存储了一个准确(精确)的数字表达法;不存储值的近似值.其中10是小数点左边和右边的数字个数之和(不包括小数点),2代表小数点右边的小数位数或数字个数.decimal(10,2)可以存储8位整数2位小数的数字.

此外,下面将对mysql中cast()和convert()的用法讲解

一、在mysql操作中我们经常需要对数据进行类型转换。此时我们应该使用的是cast()或convert()。

二、两者的对比

相同点:都是进行数据类型转换,实现的功能基本等同

不同点:两者的语法不同,cast(value as type) 、 convert(value,type)

三、所支持的类型如下:

二进制,同带binary前缀的效果 : BINARY

字符型,可带参数 : CHAR()

日期 : DATE

时间: TIME

日期时间型 : DATETIME

浮点数 : DECIMAL

整数 : SIGNED

无符号整数 : UNSIGNED

参考:https://www.cnblogs.com/yangchunze/p/6667502.html

  • 3
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值