MySQL-按数组中的JSON值排序元素?
嘿,我已经找了一整天了。进一步了解了我的问题和选择。因为我缺乏理解 我的一般问题是,我正在尝试根据JSON中的值选择行,并按所选值排序 我有一个表(元素),有两列:Person和Tags。标记包含一个JSON数组,其中可以包含多个JSON对象。对象始终具有“名称”和“排序” 理想情况下,我想做的是告诉数据库使用从元素中选择*,其中标记(有一个名为“apple”的对象)按顺序排列(匹配对象的排序值) 所以如果我给它“苹果”,它会列出:威廉,迈克尔,安娜 如果我给它“橙色”,它会列出:安娜,威廉 我一直在研究在SELECTs(子查询)中使用SELECTs,但我可以找到与JSON的正确组合。下面是我得到的最接近的,但我可以告诉它需要更先进的东西吗MySQL-按数组中的JSON值排序元素?,mysql,sql,json,database,directory-listing,Mysql,Sql,Json,Database,Directory Listing,嘿,我已经找了一整天了。进一步了解了我的问题和选择。因为我缺乏理解 我的一般问题是,我正在尝试根据JSON中的值选择行,并按所选值排序 我有一个表(元素),有两列:Person和Tags。标记包含一个JSON数组,其中可以包含多个JSON对象。对象始终具有“名称”和“排序” 理想情况下,我想做的是告诉数据库使用从元素中选择*,其中标记(有一个名为“apple”的对象)按顺序排列(匹配对象的排序值) 所以如果我给它“苹果”,它会列出:威廉,迈克尔,安娜 如果我给它“橙色”,它会列出:安娜,威廉 我
SELECT *
FROM elements
WHERE JSON_SEARCH( tags, 'one', 'apple', NULL, '$[*].name' ) IS NOT NULL
这将返回所有带有苹果标签的人员,但不会根据排序对他们进行排序
欢迎提出任何建议,提前谢谢。有一个类似的问题可能会对您有所帮助 您可以使用它,但它会变得复杂,因为您存储的是一个JSON数据数组,因此可能还需要一个子查询 不过,我会提出另一种解决方案。您是否考虑过跨多个表而不是使用JSON blob重新构造数据库 您可以有一个专门用于存储标记的表,如下所示:
+-------------+------------------------------------------------------------------+
| tagid | name
+-------------+------------------------------------------------------------------+
| 1 | apple
| 2 | orange
| 3 | banana
+-------------+------------------------------------------------------------------+
另一个用于存储人员的表:
+-------------+------------------------------------------------------------------+
| id | name
+-------------+------------------------------------------------------------------+
| 1 | William
| 2 | Anna
| 3 | Michael
+-------------+------------------------------------------------------------------+
最后是一个表,用于存储人员和标记之间的多个关系。这也是您可以存储排序顺序的地方:
+-------------+--------------+-----------+--------------------------------------+
| id | personid | tagid | sort
+-------------+--------------+-----------+--------------------------------------+
| 1 | 1 | 1 | 1
| 2 | 1 | 2 | 2
| 3 | 2 | 1 | 3
| 4 | 2 | 2 | 1
| 5 | 3 | 1 | 1
+-------------+--------------+-----------+---------------------------------------+
看起来更像这样的数据库模型将使复杂的查询变得更简单,并且不需要复杂的子查询,只需要连接。如果这对您很重要,那么它可能会提高您报告与标记相关的数据的能力。这里有一个对您有用的“好”查询。查询只需将res.*更改为res.name即可
SELECT res.* FROM (
SELECT
SUBSTRING_INDEX( JSON_UNQUOTE (JSON_SEARCH(e.tags, 'one', 'apple')),'.',1) as idx
,e.* FROM `elements` AS e ) AS res
WHERE res.idx IS NOT NULL
ORDER BY JSON_UNQUOTE(JSON_EXTRACT(res.tags,CONCAT(res.idx,'.sort')));
样本
mysql> select * from elements;
+----+---------+-------------------------------------------------------------------+
| id | Person | tags |
+----+---------+-------------------------------------------------------------------+
| 1 | William | [{"name": "apple", "sort": "1"}, {"name": "orange", "sort": "2"}] |
| 2 | Anna | [{"name": "apple", "sort": "3"}, {"name": "orange", "sort": "1"}] |
| 3 | Michael | [{"name": "apple", "sort": "2"}] |
+----+---------+-------------------------------------------------------------------+
3 rows in set (0.00 sec)
查找苹果
mysql> SELECT res.* FROM (
-> SELECT
-> SUBSTRING_INDEX( JSON_UNQUOTE (JSON_SEARCH(e.tags, 'one', 'orange')),'.',1) as idx
-> ,e.* FROM `elements` AS e ) AS res
-> WHERE res.idx IS NOT NULL
-> ORDER BY JSON_UNQUOTE(JSON_EXTRACT(res.tags,CONCAT(res.idx,'.sort')));
+----+---------+-------------------------------------------------------------------+
| id | Person | tags |
+----+---------+-------------------------------------------------------------------+
| 1 | William | [{"name": "apple", "sort": "1"}, {"name": "orange", "sort": "2"}] |
| 2 | Anna | [{"name": "apple", "sort": "3"}, {"name": "orange", "sort": "1"}] |
| 3 | Michael | [{"name": "apple", "sort": "2"}] |
+----+---------+-------------------------------------------------------------------+
3 rows in set (0.00 sec)
mysql> SELECT res.* FROM (
-> SELECT
-> SUBSTRING_INDEX( JSON_UNQUOTE (JSON_SEARCH(e.tags, 'one', 'orange')),'.',1) as idx
-> ,e.* FROM `elements` AS e ) AS res
-> WHERE res.idx IS NOT NULL
-> ORDER BY JSON_UNQUOTE(JSON_EXTRACT(res.tags,CONCAT(res.idx,'.sort')));
+------+----+---------+-------------------------------------------------------------------+
| idx | id | Person | tags |
+------+----+---------+-------------------------------------------------------------------+
| $[1] | 2 | Anna | [{"name": "apple", "sort": "3"}, {"name": "orange", "sort": "1"}] |
| $[1] | 1 | William | [{"name": "apple", "sort": "1"}, {"name": "orange", "sort": "2"}] |
+------+----+---------+-------------------------------------------------------------------+
2 rows in set (0.01 sec)
查找橙色
mysql> SELECT res.* FROM (
-> SELECT
-> SUBSTRING_INDEX( JSON_UNQUOTE (JSON_SEARCH(e.tags, 'one', 'orange')),'.',1) as idx
-> ,e.* FROM `elements` AS e ) AS res
-> WHERE res.idx IS NOT NULL
-> ORDER BY JSON_UNQUOTE(JSON_EXTRACT(res.tags,CONCAT(res.idx,'.sort')));
+----+---------+-------------------------------------------------------------------+
| id | Person | tags |
+----+---------+-------------------------------------------------------------------+
| 1 | William | [{"name": "apple", "sort": "1"}, {"name": "orange", "sort": "2"}] |
| 2 | Anna | [{"name": "apple", "sort": "3"}, {"name": "orange", "sort": "1"}] |
| 3 | Michael | [{"name": "apple", "sort": "2"}] |
+----+---------+-------------------------------------------------------------------+
3 rows in set (0.00 sec)
mysql> SELECT res.* FROM (
-> SELECT
-> SUBSTRING_INDEX( JSON_UNQUOTE (JSON_SEARCH(e.tags, 'one', 'orange')),'.',1) as idx
-> ,e.* FROM `elements` AS e ) AS res
-> WHERE res.idx IS NOT NULL
-> ORDER BY JSON_UNQUOTE(JSON_EXTRACT(res.tags,CONCAT(res.idx,'.sort')));
+------+----+---------+-------------------------------------------------------------------+
| idx | id | Person | tags |
+------+----+---------+-------------------------------------------------------------------+
| $[1] | 2 | Anna | [{"name": "apple", "sort": "3"}, {"name": "orange", "sort": "1"}] |
| $[1] | 1 | William | [{"name": "apple", "sort": "1"}, {"name": "orange", "sort": "2"}] |
+------+----+---------+-------------------------------------------------------------------+
2 rows in set (0.01 sec)
这对我来说是不可能的,事实上,我在不同的列中归档了多个JSON,并且必须为许多关系创建许多表,我认为这将更为复杂。谢谢你的回复。很抱歉听到这不是一个适合你的解决方案。另一种选择可能是在应用程序(例如API)中执行排序,而不是作为查询的一部分?