mysql - 从 Mysql 中的数组中的 Json 数据获取值

标签 mysql sql arrays json mariadb

我们将信息保存在一个 json 列中,该列包含数组中的 json 数据。

数据结构:

[
    {
        "type":"automated_backfill",
        "title":"Walgreens Sales Ad",
        "keyword":"Walgreens Sales Ad",
        "score":4
    },
    {
        "type":"automated_backfill",
        "title":"Nicoderm Coupons",
        "keyword":"Nicoderm Coupons",
        "score":4
    },
    {
        "type":"automated_backfill",
        "title":"Iphone Sales",
        "keyword":"Iphone Sales",
        "score":3
    },
    {
        "type":"automated_backfill",
        "title":"Best Top Load Washers",
        "keyword":"Best Top Load Washers",
        "score":1
    },
    {
        "type":"automated_backfill",
        "title":"Top 10 Best Cell Phones",
        "keyword":"Top 10 Best Cell Phones",
        "score":1
    },
    {
        "type":"automated_backfill",
        "title":"Tv Deals",
        "keyword":"Tv Deals",
        "score":0
    }
]

我们正在尝试:

SELECT id, ad_meta->'$**.type' FROM window_requests

返回:

enter image description here

我们希望将每种类型作为行获取,我认为这只有在存储过程中才有可能,返回整列然后在每一行上运行循环并返回数据...

或者你能想到更好的解决方案吗?

任一更新架构:

或者我们应该更改我们的数据库并将信息保存在单独的表中而不是 json 列?

然后我们可以通过添加外键轻松连接以获取数据。

谢谢。

最佳答案

我了解到您正在尝试从 JSON 数组的内容生成表结构。

您需要分两步进行:

  • 首先,将数组中的每个元素变成一条记录;为此,您可以生成一个内联数字表并使用 JSON_EXTRACT() 提取相关的 JSON 对象。

  • 然后,从每个对象中提取每个属性的值,生成新的列; -> 运算符可用于此目的。

查询:

SELECT 
    id,
    rec->'$.type' type,
    rec->'$.score' score,
    rec->'$.title' title,
    rec->'$.keyword' keyword                                   
FROM (
    SELECT t.id, JSON_EXTRACT(t.val, CONCAT('$[', x.idx, ']')) AS rec
    FROM 
        mytable t
        INNER JOIN ( 
            SELECT 0 AS idx    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 x ON JSON_EXTRACT(t.val, CONCAT('$[', x.idx, ']')) IS NOT NULL
    ) z

这将处理每个 JSON 数组最多 10 个对象(如果您期望更多,您可以添加展开查询的 UNION ALL 部分)。

this DB Fiddle 使用您的测试数据,这会产生:

| id  | type                 | score | title                     | keyword                   |
| --- | -------------------- | ----- | ------------------------- | ------------------------- |
| 1   | "automated_backfill" | 4     | "Walgreens Sales Ad"      | "Walgreens Sales Ad"      |
| 1   | "automated_backfill" | 4     | "Nicoderm Coupons"        | "Nicoderm Coupons"        |
| 1   | "automated_backfill" | 3     | "Iphone Sales"            | "Iphone Sales"            |
| 1   | "automated_backfill" | 1     | "Best Top Load Washers"   | "Best Top Load Washers"   |
| 1   | "automated_backfill" | 1     | "Top 10 Best Cell Phones" | "Top 10 Best Cell Phones" |
| 1   | "automated_backfill" | 0     | "Tv Deals"                | "Tv Deals"                |

注意:箭头运算符在 MariaDB 中不可用。您可以改用 JSON_EXTRACT(),例如:

SELECT 
    id,
    JSON_EXTRACT(rec, '$.type') type,
    JSON_EXTRACT(rec, '$.score') score,
    JSON_EXTRACT(rec, '$.title') title,
    JSON_EXTRACT(rec, '$.keyword') keyword
FROM
    ...

关于mysql - 从 Mysql 中的数组中的 Json 数据获取值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54617165/

相关文章:

java c3p0 : how can i configure autoreconnect=true?

mysql - 子组外的引用字段(where 子句中的未知列)

sql - 除 INTO 或 VALUES 子句外,不能使用组项

java - Int [][] 搜索联合整数

php - 数据库查询、检查和设置数组

mysqldbexport 不排除表 - "Variable ' foreign_key_checks' 是一个 SESSION 变量”

mysql - 例程 [procedurename] 的存储过程错误 OUT 或 INOUT 参数 1 不是 BEFORE 触发器中的变量或 NEW 伪变量

MYSQL:联合运算符添加 'total' 行

使用 CTE 的 SQL Server 2008 动态查询

python - 加载 numpy 数组时遇到问题,它们在 python 中显示 pickle 数据错误