我在mysql模式中有两个表,我们称它们为sites
和fields
。站点表如下所示:
create table if not exists sites
(
id int auto_increment
primary key,
collection_id int null,
name varchar(255) null,
properties text null,
)
;
这些字段具有以下架构
create table fields
(
id int auto_increment
primary key,
collection_id int null,
name varchar(255) null,
code varchar(255) null,
)
;
两个表可以在collection_id
列上进行连接。 sites
表将json数据存储在属性列中,其中 json对象的键是字段表中id列的值。例如,下面是一个示例json,可在属性列
{"1281":"Type A","1277":4}
上面json中的键是字段中记录的ID。
+---------+--------------+--------------+
|id | name | code |
+---------------------------------------+
| 1277 | Years | Yr |
+---------------------------------------+
| 1281 | Type | Ty |
+---------+--------------+--------------+
现在,我想输出属性json,其中键由字段名称代替id值代替。使用上面的示例,输出应类似于:
{"Type": "Type A", "Years": 4}
到目前为止,我已经尝试了以下方法
select JSON_OBJECT(fd.name, JSON_EXTRACT(st.properties, concat('$."', fd.id, '"'))) as prop
from sites as st join fields as fd on fd.collection_id = st.collection_id where st.collection_id = 145 and
JSON_EXTRACT(st.properties, concat('$."', fd.id, '"')) is not null ;
但是,这会为每个字段而不是站点生成json对象。
它输出如下内容:
+----------------------------+
| prop |
+-----------------------------+
| {"Type": "Type A"} |
| |
+----------------------------+
| {"Type": "Type B"} |
| |
+-----------------------------+
| |
| {"Year": 4} |
| |
+----------------------------+
如何修改上面的代码以获得所需的输出?还是有更好的解决方案?
答案 0 :(得分:0)
在按网站ID分组后,我使用group_concat
函数将每个网站的结果合并为一个解决方案。这是查询:
select concat('{' ,group_concat(concat('\"', cast(fd.code as char(50)), '\":' , JSON_EXTRACT(st.properties, concat('$.\"', fd.id, '\"')))), '}') as prop , st.id as site
from sites as st join fields as fd on fd.collection_id = st.collection_id
where st.collection_id = 145 and
JSON_EXTRACT(st.properties, concat('$."', fd.id, '"')) is not null
group by st.id
注意::此解决方案假定您使用的是MySQL版本5.7+,因为该版本是在引入JSON_EXTRACT
函数时开始的。如果您使用的是较低版本,请使用此answer中的UDF代替JSON_EXTRACT
。