Mysql:使用来自不同 table/column 的值更新 json 列
Mysql: Update json column with values from different table/column
我一直在尝试将 location table
中的下方 neighbors column
更新为 json 对象,如下所示,但无法以任何方式使其接近工作。对查询语法有什么想法吗?
原文table:
location
---------------
id name neighbors
1 loc1
2 loc2
3 loc3
4 loc4
5 loc5
nearby (this is join table where place & nextdoor refer to location.id)
nearby
-------------------
place nextdoor distance group
1 2 500m g1
1 3 900m g1
2 1 500m g3
2 3 100m g4
2 4 80m g4
预计更新后:
location
---------------
id name neighbors
1 loc1 {"g1":[{"name":"loc2", "distance":"500m"},{"name":"loc3", "distance":"900m"}]}
2 loc2 {"g3":[{"name":"loc1", "distance":"500m"}],"g4":[{"name":"loc3", "distance":"100m"},{"name":"loc4", "distance":"80m"}]}
3 loc3
4 loc4
5 loc5
试一试。它在 MySQL 8 上进行了测试。我将其分解为多个步骤,这样您就可以一个接一个地测试每个 CTE,看看它们是如何结合在一起的。
表格
create table location (id int, name varchar(10), neighbors json);
insert into location (id, name) values
(1, 'loc1'), (2, 'loc2'), (3, 'loc3'), (4, 'loc4'), (5, 'loc5');
create table nearby (place int, nextdoor int, distance varchar(10), mygroup varchar(10));
insert into nearby values
(1, 2, '500m', 'g1'), (1, 3, '900m', 'g1'),
(2, 1, '500m', 'g3'), (2, 3, '100m', 'g4'), (2, 4, '80m', 'g4');
更新查询
with flatten_neighbor as (
select nn.place, nn.name, l.name as nextdoorname, nn.distance, nn.mygroup
from (
select l.id, l.name, n.place, n.nextdoor, n.distance, n.mygroup
from location l
join nearby n on n.place = l.id
) nn
join location l on l.id = nn.nextdoor
),
obj_by_place as (
select *, json_object('name', nextdoorname, 'distance', distance) as jo
from flatten_neighbor
),
concat_obj as (
select place, mygroup, concat('[', group_concat(jo), ']') as jason
from obj_by_place group by place, mygroup
),
final as (
select place, json_objectagg(mygroup, jason) stuff
from concat_obj group by place
)
update location l join final f on l.id = f.place set l.neighbors = f.stuff;
结果
id | name | neighbors
-: | :--- | :-----------------------------------------------------------------------------------------------------------------------------------------------------------
1 | loc1 | {"g1": "[{\"name\": \"loc2\", \"distance\": \"500m\"},{\"name\": \"loc3\", \"distance\": \"900m\"}]"}
2 | loc2 | {"g3": "[{\"name\": \"loc1\", \"distance\": \"500m\"}]", "g4": "[{\"name\": \"loc3\", \"distance\": \"100m\"},{\"name\": \"loc4\", \"distance\": \"80m\"}]"}
3 | loc3 | null
4 | loc4 | null
5 | loc5 | null
例子
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=789fb79d10b745414ca7270a5a6ef004
更新后的另一个示例 json_extract。
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=fe651372ca754cc05eab842d6fced9a3
我一直在尝试将 location table
中的下方 neighbors column
更新为 json 对象,如下所示,但无法以任何方式使其接近工作。对查询语法有什么想法吗?
原文table:
location
---------------
id name neighbors
1 loc1
2 loc2
3 loc3
4 loc4
5 loc5
nearby (this is join table where place & nextdoor refer to location.id)
nearby
-------------------
place nextdoor distance group
1 2 500m g1
1 3 900m g1
2 1 500m g3
2 3 100m g4
2 4 80m g4
预计更新后:
location
---------------
id name neighbors
1 loc1 {"g1":[{"name":"loc2", "distance":"500m"},{"name":"loc3", "distance":"900m"}]}
2 loc2 {"g3":[{"name":"loc1", "distance":"500m"}],"g4":[{"name":"loc3", "distance":"100m"},{"name":"loc4", "distance":"80m"}]}
3 loc3
4 loc4
5 loc5
试一试。它在 MySQL 8 上进行了测试。我将其分解为多个步骤,这样您就可以一个接一个地测试每个 CTE,看看它们是如何结合在一起的。
表格
create table location (id int, name varchar(10), neighbors json);
insert into location (id, name) values
(1, 'loc1'), (2, 'loc2'), (3, 'loc3'), (4, 'loc4'), (5, 'loc5');
create table nearby (place int, nextdoor int, distance varchar(10), mygroup varchar(10));
insert into nearby values
(1, 2, '500m', 'g1'), (1, 3, '900m', 'g1'),
(2, 1, '500m', 'g3'), (2, 3, '100m', 'g4'), (2, 4, '80m', 'g4');
更新查询
with flatten_neighbor as (
select nn.place, nn.name, l.name as nextdoorname, nn.distance, nn.mygroup
from (
select l.id, l.name, n.place, n.nextdoor, n.distance, n.mygroup
from location l
join nearby n on n.place = l.id
) nn
join location l on l.id = nn.nextdoor
),
obj_by_place as (
select *, json_object('name', nextdoorname, 'distance', distance) as jo
from flatten_neighbor
),
concat_obj as (
select place, mygroup, concat('[', group_concat(jo), ']') as jason
from obj_by_place group by place, mygroup
),
final as (
select place, json_objectagg(mygroup, jason) stuff
from concat_obj group by place
)
update location l join final f on l.id = f.place set l.neighbors = f.stuff;
结果
id | name | neighbors -: | :--- | :----------------------------------------------------------------------------------------------------------------------------------------------------------- 1 | loc1 | {"g1": "[{\"name\": \"loc2\", \"distance\": \"500m\"},{\"name\": \"loc3\", \"distance\": \"900m\"}]"} 2 | loc2 | {"g3": "[{\"name\": \"loc1\", \"distance\": \"500m\"}]", "g4": "[{\"name\": \"loc3\", \"distance\": \"100m\"},{\"name\": \"loc4\", \"distance\": \"80m\"}]"} 3 | loc3 | null 4 | loc4 | null 5 | loc5 | null
例子
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=789fb79d10b745414ca7270a5a6ef004
更新后的另一个示例 json_extract。
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=fe651372ca754cc05eab842d6fced9a3