MySQL - JSON_EXTRACT尝试操作值时出现“无效的 JSON 路径表达式”错误JSON_LENGTH

MySQL - JSON_EXTRACT gives "invalid JSON path expression" error when attempting to manipulate JSON_LENGTH value

提问人:Phil 提问时间:9/29/2023 更新时间:9/29/2023 访问量:43

问:

我的表中有一个名为 Source_Data 的 JSON 列,其结构如下:

{
    "id": "1",
    "submissions": [
        {
            "requestDateTime": 123,
            "request": {},
            "response": {
                "result": "ACCEPTED",
                "submissionId": "ABC"
            }
        },
        {
            "requestDateTime": 456,
            "request": {},
            "response": {
                "result": "REJECTED",
                "submissionId": "XYZ"
            }
        }
    ]
}

我希望读取数组中的最后一个元素,以及对象中的值。因此,所需的输出将为“REJECTED”。submissionsresultresponse

如果我尝试以下操作,MySQL不会抛出错误:

SELECT
    JSON_EXTRACT(Source_Data, CONCAT('$.submissions[', JSON_LENGTH(Source_Data ->> '$.submissions'), '].response.result')) AS Submission_Response
FROM test;

然而,这显然是错误的,因为数组从 0 开始计数,所以我需要这样做,但这不起作用,并显示以下错误:JSON_LENGTH(Source_Data ->> "$.submissions") - 1

无效的 JSON 路径表达式。错误出在字符位置 14 附近。

一旦我添加 ,查询基本上就会中断。- 1

因此,有问题的查询如下所示:

SELECT
    JSON_EXTRACT(Source_Data, CONCAT('$.submissions[', JSON_LENGTH(Source_Data ->> '$.submissions') - 1, '].response.result')) AS Submission_Response
FROM test;

有关如何使这项工作的任何帮助将不胜感激,谢谢。我使用的是 MySQL 版本 5.7.25,因此无法使用“last”(我很喜欢)。

MySQL 的JSON

评论

0赞 Akina 9/29/2023
仅选择构建的路径并查看它。
0赞 Phil 9/29/2023
@Akina我已经尝试过了 - 返回.SELECT CONCAT("$.submissions[", JSON_LENGTH(Source_Data ->> "$.submissions") - 1, "].response.result") FROM test;$.submissions[1].response.result
0赞 Akina 9/29/2023
dbfiddle.uk/fWvsY22q
0赞 Phil 9/29/2023
@Akina感谢您的分享,我尝试运行最后一个查询,但它只是给了我我在问题中描述的相同错误 - imgur.com/AxoCiHi

答:

0赞 Phil 9/29/2023 #1

我已经弄清楚了这个错误的原因。表中还有另一条记录,其数组为空。因此,检索数组中条目的计算将给出,并且MySQL对JSON路径中的破折号有问题。submissions-1

因此,我修改了查询如下:

SELECT
    JSON_EXTRACT(Source_Data, 
        CONCAT(
            '$.submissions[',
            GREATEST(JSON_LENGTH(Source_Data ->> '$.submissions') - 1, 0), 
            '].response.result'
        )
    ) AS Submission_Response
FROM test;