【问题标题】:MYSQL: Find element given a JSON_ARRAY of stringsMYSQL:给定字符串的 JSON ARRAY 查找元素
【发布时间】:2019-10-09 16:11:03
【问题描述】:

我试图找出一种方法来查找给定 JSON_ARRAY 字符串的元素。我想要实现的是contains all 功能。

假设我有一个名为Movies 的表,其中包含namegenre 列,还有一个名为Genre 的表,其中包含id 列。

电影

NAME      GENRE
Batman    1 
Batman    2  
Aquaman   2  
Joker     3  
IT        4  

类型

ID   NAME
1    Drama 
2    Action  
3    Thriller  
4    Horror    

所以现在如果我有一个带有

的 JSON_ARRAY
SET @array = JSON_ARRAY("Action", "Drama");  

如何创建一个给定 JSON_ARRAY 返回Batman 的存储过程?

我认为解决方案是 SQL 递归,但我不确定...

SET @array = JSON_ARRAY("Action", "Drama");  
sproc.GetMovieGivenGenres(@array, @out_movie);
SELECT @out_movie; --> Batman

【问题讨论】:

  • 注意!电影的类型完全是虚构的!他们可能不正确;)
  • JSON 数组从何而来?

标签: mysql sql recursive-query


【解决方案1】:

我们可以尝试使用JSON_SEARCH()函数,它可以搜索JSON数组:

SELECT
    m.NAME
FROM Movies m
INNER JOIN Genre g
    ON m.GENRE = g.ID
GROUP BY
    m.NAME
HAVING
    COUNT(CASE WHEN JSON_SEARCH(@array, 'one', g.NAME) IS NOT NULL THEN 1 END) =
    JSON_LENGTH(@array);

JSON_SEARCH 函数将返回一个非NULL 值,如果在输入数组中找到给定的流派,对于每部电影。匹配电影是包含输入数组中所有类型的电影。

【讨论】:

    【解决方案2】:

    在 mySQL 8 中,您可以使用 JSON_TABLE() 将 JSON 数组转换为表。然后您可以将生成的表与您的两个表连接起来:

    SET @array = JSON_ARRAY("Action", "Drama");  
    
    select m.NAME
    from json_table(
      @array,
      '$[*]' columns (genre_name varchar(50) path '$')
    ) j
    join Genre g on g.NAME = j.genre_name
    join Movies m on m.GENRE = g.ID
    group by m.NAME
    having count(*) = json_length(@array);
    

    db-fiddle demo

    这样,MySQL 将能够使用Genre(NAME) 上的索引。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-06
      • 1970-01-01
      • 1970-01-01
      • 2017-11-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多