【发布时间】: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 行。您至少需要在嵌套选择中添加一个条件。但更好 - 一次选择加入两个表。