更改MySQL选择中的JSON字段中的值,使用来自其他JSON字段的适当值。

huangapple go评论67阅读模式
英文:

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

在DB Fiddle上查看

我正在使用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

View on DB Fiddle

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

fiddle

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

fiddle

> in general, there are no more than 15 addons to choose from. – Milen Mihalev

Expand numbers synthetic tables accordingly.

huangapple
  • 本文由 发表于 2023年6月29日 20:18:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/76580985.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定