Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL-按数组中的JSON值排序元素?_Mysql_Sql_Json_Database_Directory Listing - Fatal编程技术网

MySQL-按数组中的JSON值排序元素?

MySQL-按数组中的JSON值排序元素?,mysql,sql,json,database,directory-listing,Mysql,Sql,Json,Database,Directory Listing,嘿,我已经找了一整天了。进一步了解了我的问题和选择。因为我缺乏理解 我的一般问题是,我正在尝试根据JSON中的值选择行,并按所选值排序 我有一个表(元素),有两列:Person和Tags。标记包含一个JSON数组,其中可以包含多个JSON对象。对象始终具有“名称”和“排序” 理想情况下,我想做的是告诉数据库使用从元素中选择*,其中标记(有一个名为“apple”的对象)按顺序排列(匹配对象的排序值) 所以如果我给它“苹果”,它会列出:威廉,迈克尔,安娜 如果我给它“橙色”,它会列出:安娜,威廉 我

嘿,我已经找了一整天了。进一步了解了我的问题和选择。因为我缺乏理解

我的一般问题是,我正在尝试根据JSON中的值选择行,并按所选值排序

我有一个表(元素),有两列:Person和Tags。标记包含一个JSON数组,其中可以包含多个JSON对象。对象始终具有“名称”和“排序”

理想情况下,我想做的是告诉数据库使用从元素中选择*,其中标记(有一个名为“apple”的对象)按顺序排列(匹配对象的排序值)

所以如果我给它“苹果”,它会列出:威廉,迈克尔,安娜

如果我给它“橙色”,它会列出:安娜,威廉

我一直在研究在SELECTs(子查询)中使用SELECTs,但我可以找到与JSON的正确组合。下面是我得到的最接近的,但我可以告诉它需要更先进的东西吗

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)中执行排序,而不是作为查询的一部分?