mysql行转列,使用json_objectagg实现

使用mysql的 JSON_OBJECTAGG 聚合函数。

官网地址:

https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_json-objectagg

用数据字典来举例子

下面4张表:

dict存放的是类型,例如:基本信息,主芯片。

item 存放的是代表行的记录

head 存放的是表头 如基本信息的表头或者主芯片的表头

detail 存放的是具体数据。这个表有点不好的地方就是每个属性都得一行。detail数据会膨胀得很厉害,所以数据多谨慎使用。

如果跟我一样直接通过类型就能准确定位少量数据还是没啥问题的。

dict表和对应的数据

item表和对应的数据

head表和对应的数据

detail表和对应的数据

查询的sql ,实际怎么查询按自己需求来。

-- 查询对应表头的数据
SELECT t.id ,t.name , JSON_OBJECTAGG(d.attribute,d.attribute_value) attribute FROM 
`bd_dict` dt 
 LEFT JOIN `bd_dict_item` t  ON t.dict_id = dt.id
 LEFT JOIN `bd_dict_item_detail` d ON d.item_id = t.id
 WHERE dt.id =1  -- 查询同一类型下的 ,在我的需求中dt表的id其实相当与一张表
  GROUP BY t.id
 ;
 
-- 查询表头
SELECT dt.dict_code ,dt.dict_name , JSON_OBJECTAGG(h.attribute,h.attribute_name) head_info  FROM 
`bd_dict` dt 
 LEFT JOIN `bd_dict_item_head` h ON  h.dict_id = dt.id
 WHERE dt.id =1
  GROUP BY dt.dict_name
 ;
 

查询的表头是个json。 因为是动态列,所以表头信息也得返回给前端,表头信息和detail的数据使用相同的key来对应关系

对应的java对象

class ItemHead{

    String dictCode;

    String dictName;

   String headInfo; // json 类型可以使用String 来接受 

}

 

detail查询的结果。

如果需要对json的查询结果进行过滤,可以参考官方文档的json查询api。这里就不列举了。

虽然没有实现每个属性都对应一列,但这也算一个列转行对象。

class Phone{

    String id;

    String name;

//  示例假代码 类似这种,实际是String类型的 JSON 数据;

 Attribute attribute  ;   // ===> String attribute

}

跟下面这种差别不是很大

class Phone{

    String id;

    String name;

     String cpuNum;

   String cpuBrand;

}

下面是执行计划,其他测试暂时没做,空了看看这种sql效率会如何

每个item_head 表可以根据item 的id ,使用javaassint 生成一个POJO类,作为参数接受。也可以直接使用JSON 工具。

 

 

以上就是mysql行转列的实现。

 

 

 

跟网上其他动态列例子一样。

都使用函数实现,只是这里使用的是json的函数,可以不需要在sql中写固定表头,

 

 

 

 

网上也有存储过程的实现,具体没怎么看,看各自需求。

sql文件自取地址

https://gitee.com/zengq-s/mysql_pivot  


版权声明:本文为m673010624原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。