如何按 json 路径 mysql 内的数组值排序?
How to order by array value inside json path mysql?
我在 db table 中有一列属于 JSON 类型。
此列将存储以下值:
column 1: ["bmw", "opel", "audi"]
column 2: ["opel", "bwm", "audi"]
column 3: ["audi"]
值的顺序和总数不同,但通常有一个要存储的有效值列表。
在 UI 上,有一个 table 包含可以排序的列。当用户单击 ASC 列 Car Brand
时,我需要根据上面提到的列值对 db 的输出进行排序。
我想收到以下输出:
1: ["audi"]
2: ["audi", "bmw", "opel"]
3: ["audi", "bmw", "opel"]
我似乎无法使用 JSON 路径找到解决方案。
有人能帮帮我吗?
请不要建议以不同的方式存储值,这不是我决定的。
您不能在 MySQL 中执行此操作。
Akina在上面的评论中描述的是这样的演示:
set @j = '["opel", "bwm", "audi"]';
select * from json_table(@j, '$[*]' columns (a varchar(10) path '$')) j order by a;
+------+
| a |
+------+
| audi |
| bwm |
| opel |
+------+
然后想法是使用 JSON_ARRAYAGG() 将这些行重新组合成一个 JSON 数组。但是,这不起作用:
select json_arrayagg(a) as j from (
select * from json_table(@j, '$[*]' columns (a varchar(10) path '$')) j order by a
) as a;
+-------------------------+
| j |
+-------------------------+
| ["opel", "bwm", "audi"] |
+-------------------------+
子查询中的ORDER BY已经被提取出来。 MySQL 认为没有理由在派生的 table 中对行进行排序,它们应该作为外部查询的最后一步进行排序。
https://dev.mysql.com/doc/refman/5.7/en/aggregate-functions.html#function_json-arrayagg 说:
JSON_ARRAYAGG(col_or_expr)
Aggregates a result set as a single JSON array whose elements consist
of the rows. The order of elements in this array is undefined.
https://bugs.mysql.com/bug.php?id=94696 是 2019 年的一项功能请求,要求在使用 JSON_ARRAYAGG() 聚合元素之前对元素进行排序。该票证处于“已验证”状态,这意味着它已被接受为功能请求,但尚未实施。
在 MySQL 8.0 中还没有使用 JSON_ARRAYAGG() 以特定顺序生成数组的解决方案。
所以你能做的最好的事情就是将它们作为排序的行获取,就像我在这个答案前面的中间步骤中展示的那样,然后在你的客户端应用程序代码中按照这个顺序将它们组合成一个数组。
我在 db table 中有一列属于 JSON 类型。
此列将存储以下值:
column 1: ["bmw", "opel", "audi"]
column 2: ["opel", "bwm", "audi"]
column 3: ["audi"]
值的顺序和总数不同,但通常有一个要存储的有效值列表。
在 UI 上,有一个 table 包含可以排序的列。当用户单击 ASC 列 Car Brand
时,我需要根据上面提到的列值对 db 的输出进行排序。
我想收到以下输出:
1: ["audi"]
2: ["audi", "bmw", "opel"]
3: ["audi", "bmw", "opel"]
我似乎无法使用 JSON 路径找到解决方案。
有人能帮帮我吗?
请不要建议以不同的方式存储值,这不是我决定的。
您不能在 MySQL 中执行此操作。
Akina在上面的评论中描述的是这样的演示:
set @j = '["opel", "bwm", "audi"]';
select * from json_table(@j, '$[*]' columns (a varchar(10) path '$')) j order by a;
+------+
| a |
+------+
| audi |
| bwm |
| opel |
+------+
然后想法是使用 JSON_ARRAYAGG() 将这些行重新组合成一个 JSON 数组。但是,这不起作用:
select json_arrayagg(a) as j from (
select * from json_table(@j, '$[*]' columns (a varchar(10) path '$')) j order by a
) as a;
+-------------------------+
| j |
+-------------------------+
| ["opel", "bwm", "audi"] |
+-------------------------+
子查询中的ORDER BY已经被提取出来。 MySQL 认为没有理由在派生的 table 中对行进行排序,它们应该作为外部查询的最后一步进行排序。
https://dev.mysql.com/doc/refman/5.7/en/aggregate-functions.html#function_json-arrayagg 说:
JSON_ARRAYAGG(col_or_expr)
Aggregates a result set as a single JSON array whose elements consist of the rows. The order of elements in this array is undefined.
https://bugs.mysql.com/bug.php?id=94696 是 2019 年的一项功能请求,要求在使用 JSON_ARRAYAGG() 聚合元素之前对元素进行排序。该票证处于“已验证”状态,这意味着它已被接受为功能请求,但尚未实施。
在 MySQL 8.0 中还没有使用 JSON_ARRAYAGG() 以特定顺序生成数组的解决方案。
所以你能做的最好的事情就是将它们作为排序的行获取,就像我在这个答案前面的中间步骤中展示的那样,然后在你的客户端应用程序代码中按照这个顺序将它们组合成一个数组。