添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
安静的麻辣香锅  ·  ASP.NET Core SignalR ...·  3 月前    · 
安静的香烟  ·  jsplumb ...·  1 年前    · 

如果按照最基本的 SQL 查询方式来实现,返回的应该是类似于下面这样的结果:

商品 ID 日期 售出数量
商品1 2021-06-27 5
商品1 2021-06-26 9
商品1 2021-06-25 7
商品2 2021-06-27 7

但给前端传数据一定是用的 JSON 格式,比如接口结构可能类似于下面这样:

"商品1" : { "recentHistory" : [ "date" : "2021-06-27" , "amount" : 5 "date" : "2021-06-26" , "amount" : 9

换句话说就是,需要把同样商品 ID 下不同日期的数据聚合在一起。

于是我想,为什么不能在 SQL 查询时直接返回聚合之后的数据呢?在 SQL 这种声明式语言中实现,总比在 Java 里用命令式的方法写要轻松啊。

搜了一下发现,MySQL 居然支持直接返回 JSON 字符串格式的数据!真令人喜出望外。下面简单介绍一下。

示例数据表

为了演示方便,新建一个简单的示例表:

CREATE TABLE `mytbl`
    `id`    int,
    `name`  varchar(10),
    `value` int
INSERT INTO `mytbl` (`id`, `name`, `value`)
VALUES (1, 'A', '4'),
       (1, 'B', '8'),
       (2, 'C', '9');
idnamevalue
1A4
1B8
2C9

SQL 查询结果:

idjson
1{“A”:4,“B”:8}
2{“C”:9}

实现方法:

如果希望返回这种结构的结果,没有什么额外的捷径可走,只能使用 CONCATGROUP_CONCAT 自行把字符串拼接起来。

SQL 查询如下:

# 实现效果1
SELECT id,
       CONCAT('{', GROUP_CONCAT(CONCAT('"', `name`, '":', `value`) SEPARATOR ','),
              '}') AS `json`
FROM mytbl
GROUP BY id;

其中,内层的 CONCAT把每列拼接成 "name":value这种形式,GROUP_CONCAT, 作为分隔符把多个 "name":value拼在一起,最后外层的 CONCAT 在首尾拼接上花括号。

顺便提一句,下面效果2 的实现中用到了 JSON_OBJECT 方法来拼接 JSON 对象,但这里没有用上,这是因为 JSON_OBJECT 只能接受字符串字面量作为键,不能是变量。这里JSON 对象的键也是数据表里的值,所以不能用 JSON_OBJECT 方法。

(希望之后 JSON_OBJECT 也能够支持变量作为键)

SQL 查询结果:

idjson
1[{“name”: “A”, “value”: 4},{“name”: “B”, “value”: 8}]
2[{“name”: “C”, “value”: 9}]

实现方法:

如果希望返回这种结构的结果,有一些 MySQL 内置的 JSON 相关函数可以帮忙。

MySQL 5.7.22 及以上

5.7.22 版本及以上支持 JSON_ARRAYAGG 方法,用来把多个 JSON 对象拼接成 JSON 数组。

此外,5.7 版本及以上支持 JSON_OBJECT 方法,用来基于列数据生成 JSON对象。

利用这两个内置函数, SQL 查询可以写成很简洁的形式:

# MySQL 5.7.22 及以上,实现效果2
SELECT id,
       JSON_ARRAYAGG(JSON_OBJECT('name', name, 'value', value)) AS json
FROM mytbl
GROUP BY id;

MySQL 5.7 及以上

这种情况是不支持 JSON_ARRAYAGG 方法。还是可以利用 JSON_OBJECT 方法,但需要自己用 CONCATGROUP_CONCAT 来模拟 JSON_ARRAYAGG

# MySQL 5.7 及以上,实现效果2
SELECT id,
       CONCAT('[', GROUP_CONCAT(JSON_OBJECT('name', `name`, 'value', `value`) SEPARATOR ','),
              ']') AS `json`
FROM mytbl
GROUP BY id;

这样写出来虽然也实现了同样的效果,但可读性就差多了。我自己遇到的就是这种情况,但迫于生产库的版本不支持 JSON_ARRAYAGG 方法,只好采取这种写法。

…更早版本?

如果连 JSON_OBJECT 方法也不支持,那就只能完全用 CONCATGROUP_CONCAT 来实现了,和上面效果1 中差不多,这里就不写了。

目录背景示例数据表效果1实现方法:效果2实现方法:MySQL 5.7.22 及以上MySQL 5.7 及以上..更早版本?背景这周做一个内部 CMS 需求,要提供一个接口查询最近两周内,某几种商品每天的售卖数量。如果按照最基本的 SQL 查询方式来实现,返回的应该是类似于下面这样的结果:表1商品 ID日期售出数量商品12021-06-275商品12021-06-269商品12021-06-257………商品22021-06-277
最近在做新老系统的切换,老系统有很多数据不能丢弃,实在太懒,不想写程序来迁移数据,脚本也会的不多,只能写写sql, 现在写的差不多了,感觉自己收获还是不小。常去触及自己盲区,总能有所收获,做做总结: 1、uuid() 和 uuid_short() uuid() 查询时多列的值是一个不会变化,而uuid_short() 不会重复每次会加1 非常适合当主键来使用。 case when a=1 then 1 end b 查询时的判断条件用处特别多。 3、多行合并 和多列合并函数 conca
order_info-订单信息表 CREATE TABLE `order_info` ( `order_id` varchar(32) NOT NULL COMMENT '订单id', `user_id` varchar(64) DEFAULT NULL COMMENT '买家id', `user_phone` varchar(32) DEFAULT NULL COMMENT '下单钉钉绑定的手机号', `belong_group` char(1) DEFAULT NU
你可以使用 MySqlJSON 函数来将行转换为 JSON 字符串。例如: SELECT JSON_OBJECT('name', name, 'age', age, 'email', email) FROM users; 这将会从 users 表中选择所有行,并将每一行的数据转换为一个 JSON 对象。对象的键名为 name, age, 和 email,值分别对应于该行中同名的列。 如果你...
需求:做一个出题的页面,希望把题目从MySQL数据库抽取出来后,转换json格式,待用。(注:其实可以后端直接写好题目格式,但不太想用这种方法。)直接上代码:$sql = "SELECT id,leixing,tigan,A,B,C,D,E,F,daan,jiexi FROM danyuanceyan"; $retval = mysqli_query($conn,$sql); $row=arra...
利用函数:group_concat(),实现一个ID对应多个名称时,原本为多行数据,把名称合并一行。 其完整语法: GROUP_CONCAT(expr) 该函数返回带有来自一个组的连接的非NULL值的字符串结果。其完整的语法如下所示: GROUP_CONCAT([DISTINCT] expr [,expr …] [ORDER BY {unsigned_integer | col_name | expr} [ASC | DESC] [,col_name …]] [SEPARATOR str_val]) mysql> SELECT student_name, -> GROUP_CONCAT(te
mysql pgsql 按照指定字段分组实现多行合并一行数据库服务器环境原表结构和数据studentsscorespgsqlSQL结果mysqlSQL结果相关文章导读 数据库服务器环境 使用 字段->’$.json属性’ 进行查询条件 使用json_extract函数查询,json_extract(字段,"$.json属性") 根据json数组查询,用JSON_CONTAINS(字段,JSON_OBJECT(‘json属性’, “内容”)) MySQL5.7以上支持JSON的操作,以及增加了JSON存储类型 一般数据库存储j...
MySQL 8.0.3(及更高版本)支持两种合并算法,由函数JSON_MERGE_PRESERVE()和JSON_MERGE_PATCH()实现。它们在处理重复键的方式上有所不同:JSON_MERGE_PRESERVE()保留重复键的值,而JSON_MERGE_PATCH()丢弃除最后一个值之外的所有值。接下来的几段将解释这两个函数中的每一个都如何处理 JSON 文档(即对象和数组)的不同组合的合并JSON_MERGE_PRESERVE()与以前版本的MySQL(在MySQL...