如何在 MySQL 5.7 中的 JSON 数组中获取唯一/不同的元素

Posted

技术标签:

【中文标题】如何在 MySQL 5.7 中的 JSON 数组中获取唯一/不同的元素【英文标题】:How to get unique / distinct elements inside JSON array in MySQL 5.7 【发布时间】:2020-01-22 21:46:22 【问题描述】:

我有一个带有一些 JSON 列的非规范化表的 mysql 5.7。我需要为数组列的每行提取唯一/不同的值。

例如:["a", "b", "b", "a", "c"] 预期输出应为 ["a", "b", "c"];

SET @json = '["a", "b", "b", "a", "c"]'; 我需要在此列表中获取唯一值。

["a", "b", "c"];

【问题讨论】:

看起来更像是您应该在应用程序级别而不是直接从数据库中执行的操作 或者,如果您想对这些值使用像DISTINCT 这样的 SQL 操作,则将每个值存储在单独的行中。换句话说,仅使用 JSON 逐字存储和获取整个 JSON 文档。不要期望使用 SQL 操作来搜索、排序或聚合 JSON 文档的元素,就好像它们是离散的关系数据一样。 您可以查看 MySQL 8.0.17 中的多值索引来索引所有数组条目并查找不同的文档标识符。 【参考方案1】:

在 MySQL 中,没有直接的方法可以从 JSON 数组中获取不同的值。一种方法可以是utilize a Sequence/Number Generator table concept。此序列表可以用作派生表(子查询),或者您可以创建一个永久表,在数据库中存储数字。

然后我们将使用这个序列表从数组中的第一个键、第二个键、第三个键等处取出JSON_EXTRACT() 值。一旦我们提取了单独行中的值,我们就可以简单地使用DISTINCT 来从中获取唯一值。之后,我们可以使用JSON_ARRAYAGG() 函数将这些唯一值重新聚合为 JSON 数组。

架构 (MySQL v5.7)

SET @json = '["a", "b", "b", "a", "c"]';

查询

SELECT Json_arrayagg(dt.val) AS unq_json_array
FROM   (SELECT DISTINCT Json_extract(@json, Concat('$[', seq.n, ']')) AS val
        FROM   (SELECT 0 AS n UNION ALL SELECT 1 UNION ALL
                SELECT 2 UNION ALL SELECT 3 UNION ALL 
                SELECT 4 UNION ALL SELECT 5 UNION ALL
                SELECT 6 UNION ALL SELECT 7 UNION ALL
                SELECT 8 UNION ALL SELECT 9) AS seq) AS dt
WHERE  dt.val IS NOT NULL;

结果

| unq_json_array  |
| --------------- |
| ["a", "b", "c"] |

View on DB Fiddle

【讨论】:

【参考方案2】:

以下内容可能对使用 MySQL 8

的人有所帮助

您可以使用JSON_TABLEJSON_OBJECTAGGJSON_KEYS 的组合来轻松完成此操作。太糟糕了,我们不能做像JSON_ARRAYAGG(DISTINCT item) 这样的事情。

例如:

SET @json = '["a", "b", "b", "a", "c"]';

SELECT JSON_KEYS(JSON_OBJECTAGG(item, ""))
FROM JSON_TABLE(@json, '$[*]'
    COLUMNS(
        item TEXT PATH '$'
    )
) as items;

我还制作了一个 DBFiddle 来展示我的作品:https://www.db-fiddle.com/f/6hgSEXPJWcm2CH8K16z6gQ/0

JSON_TABLE https://dev.mysql.com/doc/refman/8.0/en/json-table-functions.html

JSON 搜索功能:https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html

【讨论】:

以上是关于如何在 MySQL 5.7 中的 JSON 数组中获取唯一/不同的元素的主要内容,如果未能解决你的问题,请参考以下文章

mysql 5.7 json 类型 json 数组类型 普通字符串类型 10w数据 查询速度差异

MySQL 5.7新支持--------Json类型实战

MySQL 5.7新支持--------Json索引创建实战

MySQL 5.7+,嵌套路径中的 JSON_SET 值

MySQL 5.7 JSON_EXTRACT 不适用于对象中的带引号的字符串:[错误]“字符串中缺少右引号”

mysql 5.7 json 增删改查怎么写