【问题标题】:The index on JSON_EXTRACT function doesn't returns the dataJSON_EXTRACT 函数的索引不返回数据
【发布时间】:2019-09-05 13:30:32
【问题描述】:

我的问题是当我尝试使用 mysql 函数 JSON_EXTRACT 获取数据时,我使用索引 [0] 并且一切正常,但是当我要求下一个 [1] 时,返回 null。我已经尝试不使用索引来知道搜索如何返回我所有的 json 数据,并且当我尝试将索引位置超过 0 位置时,不返回任何数据,只是返回 null。这是我的示例代码:

set @example = '{"product":{
                            "id_product":1, 
                            "quantity":1
                           },
                 "product":{
                            "id_product":3, 
                            "quantity":4
                            },
                 "product":{
                            "id_product":5, 
                            "quantity":2
                            }
                 }';

select JSON_EXTRACT(@example, '$.product[0].id_product'); -- Returns '1'
select JSON_EXTRACT(@example, '$.product[1].id_product'); -- Returns null, should be '3'

如果不是真的像这样使用,我想知道它是如何工作的。
提前致谢。

【问题讨论】:

    标签: mysql json


    【解决方案1】:

    最后一个重复键获胜

    11.6 The JSON Data Type :: Normalization, Merging, and Autowrapping of JSON Values

    ...

    这种“最后一个重复键获胜”行为是 RFC 7159 建议的,并且由大多数 JavaScript 实现 解析器。

    ...

    在 8.0.3 之前的 MySQL 版本中,具有与文档中较早发现的键重复的键的成员被丢弃。

    ...

    示例:

    mysql> SELECT VERSION();
    +-----------+
    | VERSION() |
    +-----------+
    | 8.0.15    |
    +-----------+
    1 row in set (0.00 sec)
    
    mysql> SET @`example` := '{
        '>   "product": {
        '>     "id_product": 1,
        '>     "quantity": 1
        '>   },
        '>   "product": {
        '>     "id_product": 3,
        '>     "quantity": 4
        '>   },
        '>   "product": {
        '>     "id_product": 5,
        '>     "quantity": 2
        '>   }
        '> }';
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> SELECT JSON_VALID(@`example`);
    +------------------------+
    | JSON_VALID(@`example`) |
    +------------------------+
    |                      1 |
    +------------------------+
    1 row in set (0.01 sec)
    
    mysql> SELECT JSON_LENGTH(@`example`);
    +-------------------------+
    | JSON_LENGTH(@`example`) |
    +-------------------------+
    |                       1 |
    +-------------------------+
    1 row in set (0.00 sec)
    
    mysql> SELECT JSON_EXTRACT(@`example`, '$.product');
    +---------------------------------------+
    | JSON_EXTRACT(@`example`, '$.product') |
    +---------------------------------------+
    | {"quantity": 2, "id_product": 5}      |
    +---------------------------------------+
    1 row in set (0.00 sec)
    

    一些选项

    选项 0

    mysql> SET @`example` := '{
        '>   "product_0": {
        '>     "id_product": 1,
        '>     "quantity": 1
        '>   },
        '>   "product_1": {
        '>     "id_product": 3,
        '>     "quantity": 4
        '>   },
        '>   "product_2": {
        '>     "id_product": 5,
        '>     "quantity": 2
        '>   }
        '> }';
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> SELECT JSON_VALID(@`example`);
    +------------------------+
    | JSON_VALID(@`example`) |
    +------------------------+
    |                      1 |
    +------------------------+
    1 row in set (0.00 sec)
    
    mysql> SELECT JSON_LENGTH(@`example`);
    +-------------------------+
    | JSON_LENGTH(@`example`) |
    +-------------------------+
    |                       3 |
    +-------------------------+
    1 row in set (0.00 sec)
    
    mysql> SELECT
        ->   JSON_EXTRACT(@`example`, '$.product_0.id_product'),
        ->   JSON_EXTRACT(@`example`, '$.product_1.id_product'),
        ->   JSON_EXTRACT(@`example`, '$.product_2.id_product')\G
    *************************** 1. row ***************************
    JSON_EXTRACT(@`example`, '$.product_0.id_product'): 1
    JSON_EXTRACT(@`example`, '$.product_1.id_product'): 3
    JSON_EXTRACT(@`example`, '$.product_2.id_product'): 5
    1 row in set (0.00 sec)
    

    选项 1

    mysql> SET @`example` := '[
        '> {
        '>   "product": {
        '>     "id_product": 1,
        '>     "quantity": 1
        '>   }
        '> },
        '> {
        '>   "product": {
        '>     "id_product": 3,
        '>     "quantity": 4
        '>   }
        '> },
        '> {
        '>   "product": {
        '>     "id_product": 5,
        '>     "quantity": 2
        '>   }
        '> }]';
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> SELECT JSON_VALID(@`example`);
    +------------------------+
    | JSON_VALID(@`example`) |
    +------------------------+
    |                      1 |
    +------------------------+
    1 row in set (0.00 sec)
    
    mysql> SELECT JSON_LENGTH(@`example`);
    +-------------------------+
    | JSON_LENGTH(@`example`) |
    +-------------------------+
    |                       3 |
    +-------------------------+
    1 row in set (0.00 sec)
    
    mysql> SELECT
        ->   JSON_EXTRACT(@`example`, '$[0].product.id_product'),
        ->   JSON_EXTRACT(@`example`, '$[1].product.id_product'),
        ->   JSON_EXTRACT(@`example`, '$[2].product.id_product')\G
    *************************** 1. row ***************************
    JSON_EXTRACT(@`example`, '$[0].product.id_product'): 1
    JSON_EXTRACT(@`example`, '$[1].product.id_product'): 3
    JSON_EXTRACT(@`example`, '$[2].product.id_product'): 5
    1 row in set (0.00 sec)
    

    【讨论】:

    • 太好了,我想虽然使用支持 json 的 mysql 版本 5.7(我正在使用的),但不能正常工作,更好的方法是像你一样使用 8.0。
    • @RamonB.C.:在 MySQL 5.7 中,这两个选项都可以正常工作,请参阅 dbfiddle
    猜你喜欢
    • 2020-09-13
    • 1970-01-01
    • 2018-11-14
    • 1970-01-01
    • 1970-01-01
    • 2019-08-15
    • 1970-01-01
    • 1970-01-01
    • 2020-01-09
    相关资源
    最近更新 更多