MySQL将多列转换为JSON

时间:2016-12-15 14:49:55

标签: mysql json

我试图将一个表中的多个列转换为mysql数据库(版本5.7.16)中另一个表中的单个JSON。我想使用SQL查询。

第一张表看起来像这样

   CREATE TABLE `log_old` (
    `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    `temperature` DECIMAL(5,2) NULL DEFAULT NULL,
    `heating_requested` BIT(1) NULL DEFAULT NULL,
    PRIMARY KEY (`id`),
   )COLLATE='utf8_general_ci'
   ENGINE=InnoDB;

第二张表看起来像这样

    CREATE TABLE `log_new` (
    `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    'data' JSON,
    PRIMARY KEY (`id`),
    )COLLATE='utf8_general_ci'
    ENGINE=InnoDB;

数据JSON在log_new表的所有行中具有相同的格式,它应该如下所示

{
    temperature: value,
    heatingRequested: false
}

例如log_old看起来像这样

 +--+-----------+-----------------+
 |id|temperature|heating_requested|
 +--+-----------+-----------------+
 |1 |    12     |        true     |
 +--+-----------+-----------------+
 |2 |    14     |        true     |
 +--+-----------+-----------------+
 |3 |    20     |        false    |
 +--+-----------+-----------------+

我希望log_new看起来像这样

 +--+-----------------------------------------+
 |id|              data                       |
 +--+-----------------------------------------+
 |1 |{temperature:12, heatingRequested: true} | 
 +--+-----------------------------------------+
 |2 |{temperature:14, heatingRequested: true} | 
 +--+-----------------------------------------+
 |3 |{temperature:20, heatingRequested: false}| 
 +--+-----------------------------------------+

我尝试使用JSON_INSERT()

    SELECT JSON_INSERT((SELECT data  FROM log_new  ), '$.temperature',
   (SELECT temperature FROM log_old));

但是这个抛出错误"子查询返回超过1行" 我只提供了可以使用的解决方案,并且逐行进行,但这可能需要很长时间

   DELIMITER //  
   CREATE PROCEDURE doLog()
   BEGIN
    SELECT COUNT(*) into @length from log_zone;  
    SET @selectedid = 1;
    WHILE @selectedid < @length DO
        SELECT temperature,heating_requested INTO @temperature,@heating_requested FROM log_old where id=@selectedid;    
        SELECT   JSON_OBJECT('temperature',@temperature,'heatingRequested',@heating_requested) into @data_json;
        SET @selectedid = @selectedid + 1;
        INSERT INTO log_new (data) VALUES (@data_json);
     END WHILE;
    END;
    //
    CALL doLog()

2 个答案:

答案 0 :(得分:4)

由于您的所有数据都是单行提供的,因此您不需要使用子查询或循环来构建json对象。

您可以尝试以下内容:

INSERT INTO log_new (data)
   SELECT json_object('temperature',log_old.temperature,'heatingRequested',log_old.heating_requested) 
   FROM   log_old

答案 1 :(得分:0)

使用编程语言或BI工具。您的问题已被深思熟虑,但我想念的是为什么这一定要在mysql中进行?

尽管许多RDMS具有报告附件,但RDMS并非旨在提供这种低级操作。您正在进入报告领域,可能需要集中精力查看数据库外部的数据。最好使用Node,PHP,Python以及几乎任何具有强大mysql支持的实际编程语言(几乎每种现代语言都可以)为您服务。 BI工具包括多个免费选项,例如Pentaho/Kettle和Google的Data Studio,以及无数的商业BI选项,例如Tableau等。

我坚信存储过程尽管占有一席之地,但不应对应用程序逻辑负责。