【问题标题】:MySQL convert multiple columns into JSONMySQL 将多列转换为 JSON
【发布时间】:2017-05-01 05:23:55
【问题描述】:

我正在尝试将一个表中的多个列转换为 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()

【问题讨论】:

  • SELECT JSON_INSERT((SELECT data FROM log_new ), '$.temperature', (SELECT temperature FROM log_old)); 中的两个子查询都返回多行,因此错误是正确的。检查插入选择语法 - dev.mysql.com/doc/refman/5.7/en/insert-select.html - 并将您的函数重写为一个语句,该语句将从 select json_object(... 对整个表进行批量插入
  • INSERT INTO log_new (data) SELECT JSON_OBJECT('temperature',(SELECT temperature FROM log_old)); 你是这样想的吗?我不确定我是否理解你。
  • 嵌套选择仍然会在每行外部选择中产生超过 1 行。您至少需要在嵌套选择中添加一个条件。但更好 - 一次选择加入两个表。

标签: mysql json


【解决方案1】:

由于您的所有数据都在单行中可用,因此您无需使用子查询或循环来构建 json 对象。

你可以试试这样的:

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

【讨论】:

    【解决方案2】:

    使用编程语言或 BI 工具。您的问题经过深思熟虑,但我缺少的是为什么这必须在 mysql 中?

    虽然许多 RDMS 都有报告插件,但并不打算提供这种低级别的操作。您正在进入一个报告领域,可能需要关注数据库之外的数据视图。最好使用 Node、PHP、Python 以及几乎任何具有强大 mysql 支持的实际编程语言(这几乎是所有现代语言)。 BI 工具包括几个免费选项,例如 Pentaho/Kettle 和 Google 的 Data Studio,以及无数商业 BI 选项,例如 Tableau 等。

    我坚信存储过程虽然有一个位置,但不应该负责应用程序逻辑。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-22
      • 2018-05-01
      • 1970-01-01
      • 2020-01-20
      • 2014-08-23
      • 2020-03-10
      相关资源
      最近更新 更多