mysql json 数组_列出MySQL JSON字段的所有数组元素

bd96500e110b49cbb3cd949968f18be7.png

I have a JSON field to save post's tags.

id:1, content:'...', tags: ["tag_1", "tag_2"]

id:2, content:'...', tags: ["tag_3", "tag_2"]

id:3, content:'...', tags: ["tag_1", "tag_2"]

I just want to list all tags with their popularities (or even without them) something like this:

tag_2: 3,

tag_1: 2,

tag_3: 1

解决方案

Here's the setup:

create table t ( id serial primary key, content json);

insert into t set content = '{"tags": ["tag_1", "tag_2"]}';

insert into t set content = '{"tags": ["tag_3", "tag_2"]}';

insert into t set content = '{"tags": ["tag_1", "tag_2"]}';

If you know the maximum number of tags in any tag array, you can extract all the tags using UNION:

select id, json_extract(content, '$.tags[0]') AS tag from t

union

select id, json_extract(content, '$.tags[1]') from t;

+----+---------+

| id | tag |

+----+---------+

| 1 | "tag_1" |

| 2 | "tag_3" |

| 3 | "tag_1" |

| 1 | "tag_2" |

| 2 | "tag_2" |

| 3 | "tag_2" |

+----+---------+

You need as many unioned subqueries as the number of tags in the longest array.

Then you can put this in a derived table and perform an aggregation on it:

select tag, count(*) as count

from (

select id, json_extract(content, '$.tags[0]') as tag from t

union

select id, json_extract(content, '$.tags[1]') from t

) as t2

group by tag

order by count desc;

+---------+-------+

| tag | count |

+---------+-------+

| "tag_2" | 3 |

| "tag_1" | 2 |

| "tag_3" | 1 |

+---------+-------+

This would be easier if you stored tags in a second table instead of in a JSON array:

create table tags ( id bigint unsigned, tag varchar(20) not null, primary key (id, tag));

insert into tags set id = 1, tag = 'tag_1';

insert into tags set id = 1, tag = 'tag_2';

insert into tags set id = 2, tag = 'tag_3';

insert into tags set id = 2, tag = 'tag_2';

insert into tags set id = 3, tag = 'tag_1';

insert into tags set id = 3, tag = 'tag_2';

select tag, count(*) as count

from tags

group by tag

order by count desc;

+-------+-------+

| tag | count |

+-------+-------+

| tag_2 | 3 |

| tag_1 | 2 |

| tag_3 | 1 |

+-------+-------+

This solutions works no matter how many tags per id you have. You don't need to know the max length of the list of tags per id.

JSON is nice when you need to store a 'document' of semi-structured data, but only when you treat the document as one irreducible data value. As soon as you need to access elements of the document and apply relational operations to them, the document-oriented approach shows its weakness.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值