【问题标题】:Getting Values From Json Data Inside Array in Mysql从 Mysql 中的数组内部的 Json 数据中获取值
【发布时间】:2019-07-04 03:45:49
【问题描述】:

我们将信息保存在一个 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

返回:

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

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

任一更新架构:

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

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

谢谢。

【问题讨论】:

    标签: mysql sql arrays json unnest


    【解决方案1】:

    我了解到您正在尝试从 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
        ...
    

    【讨论】:

    • 但它不适用于 MariaDB !我认为是因为箭头运算符“->”?
    • @FurqanFreed :是的,看起来 MariaDB 不支持 ->,我更新了我的答案以使用 JSON_EXTRACT() 提供替代方案
    猜你喜欢
    • 2022-01-20
    • 2013-04-04
    • 1970-01-01
    • 2014-10-08
    • 1970-01-01
    • 2019-08-19
    • 2017-09-28
    • 1970-01-01
    相关资源
    最近更新 更多