英文:
Change value in json field with the appropriate values from other json field in a MySQL select
问题
我有以下简化的架构和数据:
架构 (MySQL v5.7.22):
CREATE TABLE `config_remap` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(200),
  `addons` json,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `products` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `product_name` varchar(500) DEFAULT NULL,
  `requested_remap_id` int(11) DEFAULT NULL,
  `requested_addons` json, 
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `config_remap` (`id`, `name`, `addons`) 
VALUES(1, 'Remap 1', 
'[{ "id": 0, "name": "Addon 0" },
  { "id": 1, "name": "Addon 1" },
  { "id": 2, "name": "Addon 2" }
]');
INSERT INTO `products` (`id`, `product_name`, `requested_remap_id`, `requested_addons`) 
VALUES (1, 'Audi A4', 1, '["0", "2"]');
和以下查询:
select products.id, products.product_name, products.requested_addons, config_remap.name as requested_addon
from products
    left join config_remap on config_remap.id = products.requested_remap_id
这将产生以下结果:
| id | product_name | requested_addons | requested_addon | 
|---|---|---|---|
| 1 | Audi A4 | ["0", "2"] | Remap 1 | 
我想要更改查询,以便它可以使用config_remap.addons中的名称替换requested_addons中的ID。所以预期的结果应该类似于这样:
| id | product_name | requested_addons | requested_addon | 
|---|---|---|---|
| 1 | Audi A4 | ["Addon 0", "Addon 2"] | Remap 1 | 
我正在使用MySQL 5.7.22
英文:
I have the following simplified schema and data:
Schema (MySQL v5.7.22):
CREATE TABLE `config_remap` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(200),
  `addons` json,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `products` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `product_name` varchar(500) DEFAULT NULL,
  `requested_remap_id` int(11) DEFAULT NULL,
  `requested_addons` json, 
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `config_remap` (`id`, `name`, `addons`) 
VALUES(1, 'Remap 1', 
'[{"id": 0,"name": "Addon 0"},
  {"id": 1,"name": "Addon 1"},
  {"id": 2,"name": "Addon 2"}
]');
INSERT INTO `products` (`id`, `product_name`, `requested_remap_id`, `requested_addons`) 
VALUES (1, 'Audi A4', 1, '[\"0\", \"2\"]');
And the following query:
select products.id, products.product_name, products.requested_addons, config_remap.name as requested_addon
from products
    left join config_remap on config_remap.id = products.requested_remap_id
Which produces the following results:
| id | product_name | requested_addons | requested_addon | 
|---|---|---|---|
| 1 | Audi A4 | ["0", "2"] | Remap 1 | 
I want to change the query so it can replace the IDs of the requested_addons with their names from the config_remap.addons. So the expected result should be similar to this:
| id | product_name | requested_addons | requested_addon | 
|---|---|---|---|
| 1 | Audi A4 | ["Addon 0", "Addon 2"] | Remap 1 | 
I'm using MySQL 5.7.22
答案1
得分: 1
SELECT products.id, 
       products.product_name,
       JSON_ARRAYAGG(config_remap.addon_name) requested_addons, 
       config_remap.name requested_addon
FROM (
  SELECT cr.id, cr.name, 
         JSON_UNQUOTE(JSON_EXTRACT(cr.addons, CONCAT('$.', numbers.pos, '.id'))) addon_id, 
         JSON_UNQUOTE(JSON_EXTRACT(cr.addons, CONCAT('$.', numbers.pos, '.name'))) addon_name
  FROM config_remap cr
  CROSS JOIN (SELECT 0 pos UNION SELECT 1 UNION SELECT 2 UNION SELECT 3) numbers
  ) config_remap
JOIN (
  SELECT pr.id, pr.product_name,  pr.requested_remap_id, 
         JSON_UNQUOTE(JSON_EXTRACT(pr.requested_addons, CONCAT('$.', numbers.pos))) addon_id
  FROM products pr
  CROSS JOIN (SELECT 0 pos UNION SELECT 1 UNION SELECT 2 UNION SELECT 3) numbers
  ) products USING (addon_id)
GROUP BY 1, 2, 4;
| id | product_name | requested_addons | requested_addon | 
|---|---|---|---|
| 1 | Audi A4 | ["Addon 0", "Addon 2"] | Remap 1 | 
In general, there are no more than 15 addons to choose from. – Milen Mihalev
Expand numbers synthetic tables accordingly.
英文:
SELECT products.id, 
       products.product_name,
       JSON_ARRAYAGG(config_remap.addon_name) requested_addons, 
       config_remap.name requested_addon
FROM (
  SELECT cr.id, cr.name, 
         JSON_UNQUOTE(JSON_EXTRACT(cr.addons, CONCAT('$[', numbers.pos, '].id'))) addon_id, 
         JSON_UNQUOTE(JSON_EXTRACT(cr.addons, CONCAT('$[', numbers.pos, '].name'))) addon_name
  FROM config_remap cr
  CROSS JOIN (SELECT 0 pos UNION SELECT 1 UNION SELECT 2 UNION SELECT 3) numbers
  ) config_remap
JOIN (
  SELECT pr.id, pr.product_name,  pr.requested_remap_id, 
         JSON_UNQUOTE(JSON_EXTRACT(pr.requested_addons, CONCAT('$[', numbers.pos, ']'))) addon_id
  FROM products pr
  CROSS JOIN (SELECT 0 pos UNION SELECT 1 UNION SELECT 2 UNION SELECT 3) numbers
  ) products USING (addon_id)
GROUP BY 1, 2, 4;
| id | product_name | requested_addons | requested_addon | 
|---|---|---|---|
| 1 | Audi A4 | ["Addon 0", "Addon 2"] | Remap 1 | 
> in general, there are no more than 15 addons to choose from. – Milen Mihalev
Expand numbers synthetic tables accordingly.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论