MySQL JSON:在子数组中找到同级元素的值

时间:2019-05-21 14:17:59

标签: mysql json mariadb

我的MariaDB 10.2的JSON(LONGTEXT)类型列中具有以下(伪)JSON

{"order":
    {"otherstuff":...},
    {"dates":
        [
            {
            "typeId":2,
            "date":"2019-05-21 09:00:00"
            },
            {
            "typeId":4,
            "date":"2019-05-21 10:00:00"
            }
        ]
    }
}

我需要的是订单的日期,而我知道我需要哪种类型(4)。 订单可以具有多个由其typeId标识的日期。 typeId 4并不总是排在第二位。

SELECT JSON_UNQUOTE(JSON_SEARCH(`json`, 'one', 4, NULL, '$.dates[*].typeId'))
// gives me: $.dates[1].typeId

我现在的第一个想法是使用日期加上REPLACE typeId,但这抱怨混合排序规则。 我将如何(更优雅地)在此处引用“日期”值?

此外,该查询应该是表中GENERATED列的表达式。由于日期id4不一定适用于每个订单,因此我尝试了以下方法:

SELECT IF(4 IN (JSON_EXTRACT(json, '$.dates[*].typeId')), 'yes', 'no')
// above condition evaluates to [2, 4]

我已经修剪掉了'['和']',但是如果数组中的第4个(它是数组?),它只会给我一个“是”。 因此(不带括号):

[4, 7]->是

[2, 4]->否

我假设这不会被识别为值的数组,而是一个字符串。那么,如果我的针处于第一位置,为什么它会给我“是”?

我显然要使用日期和NULL,而不是是和否。

MySQL JSON函数对我来说是很新的。所以也许有人可以指出我正确的方向?

1 个答案:

答案 0 :(得分:0)

尝试:

选项1

SELECT
  JSON_UNQUOTE(
    JSON_EXTRACT(
      `json`,
      REPLACE(
        JSON_UNQUOTE(
          JSON_SEARCH(
            `json`,
            'one',
            4,
            NULL,
            '$.order.dates[*].typeId'
          )
        ),
        'typeId',
        'date'
      )
    )
  ) `date`;

选项2

SELECT
  IF(
    JSON_CONTAINS(
      JSON_EXTRACT(
        `json`,
        '$.order.dates[*].typeId'
      ),
      4
    ),
    'yes',
    'no'
  ) `exists`;

请参见dbfiddle