使用 SQL 将 json 数据列表字段转换为列

Posted

技术标签:

【中文标题】使用 SQL 将 json 数据列表字段转换为列【英文标题】:Transforming json data list field to columns with SQL 【发布时间】:2021-01-01 22:46:59 【问题描述】:

目前我的 DB(mariaDB) 中有一个名为 data 的列,其中包含一个 json 列表:

ID   | data
1    | '["section1","section2","section3"]'
2    | '["section2","section4"]'

我想把它变成这样的东西:

id   | section1     | section2     | section3         | section4
1    | 1            | 1            | 1                | 0
2    | 0            | 1            | 0                | 1

意味着所有字段中的所有可能值都成为列,如果相应的行存在该列表项,则获取值1,如果不存在则获取0

有没有办法通过查询来转换它?

【问题讨论】:

【参考方案1】:

考虑:

select 
    id, 
    data ->> '$[0]' section1, 
    data ->> '$[1]' section2, 
    data ->> '$[2]' section3, 
    data ->> '$[3]' section4 
from mytable

或者使用json_extract():

select 
    id, 
    json_unqote(json_extract(data, '$[0]')) section1, 
    json_unqote(json_extract(data, '$[1]')) section2, 
    json_unqote(json_extract(data, '$[2]')) section3, 
    json_unqote(json_extract(data, '$[3]')) section4 
from mytable

【讨论】:

查询 1 - MariaDB 不支持 ->->> 运算符;查询 2 - 你是主动地转动,而不是按价值转动。 fiddle【参考方案2】:
SELECT 
    id, 
    JSON_LENGTH(JSON_SEARCH(data, 'all', 'section1')) section1, 
    JSON_LENGTH(JSON_SEARCH(data, 'all', 'section2')) section2, 
    JSON_LENGTH(JSON_SEARCH(data, 'all', 'section3')) section3, 
    JSON_LENGTH(JSON_SEARCH(data, 'all', 'section4')) section4 
from test;

如果您需要零而不是 NULL,则使用 COALESCE() 包装表达式。

如果单独的data 值不能包含重复值(这是由相应的约束提供的),或者如果您不需要值数量但只有它们的存在,您可以使用

select 
    id, 
    JSON_CONTAINS(data, '"section1"') section1, 
    JSON_CONTAINS(data, '"section2"') section2, 
    JSON_CONTAINS(data, '"section3"') section3, 
    JSON_CONTAINS(data, '"section4"') section4 
from test;

fiddle

PS。如果可能的sectionX 值列表是不确定的或动态的,那么您必须使用带有动态 SQL 的存储过程。

【讨论】:

以上是关于使用 SQL 将 json 数据列表字段转换为列的主要内容,如果未能解决你的问题,请参考以下文章

将 bigquery json 字符串转换为列

如何解压缩数据框列中存在的 json 的键,值将转换为键作为列,而使用 python 将其值转换为列?

我可以使用 AWS Glue 将 S3 上的 json 数据转换为列格式并将其推送到 Redshift 吗?

使用 SQL 将数据从行转换为列

ANSI sql将行动态转换为列数据

PCB SQL MS 将多行有序数据转为一行数据(一列转一行)