MySQL - 如何按值在 IN 语句中使用子查询

Posted

技术标签:

【中文标题】MySQL - 如何按值在 IN 语句中使用子查询【英文标题】:MySQL - How to use subquery into IN statement by value 【发布时间】:2010-11-17 10:18:21 【问题描述】:

问题是获取表列数据并将其用作IN函数的值列表;

对于这个例子,我创建了 2 个表:电影和流派

表“电影”包含 3 列:id、名称和流派。 表“流派”包含 2 列:id 和 name。

+- movies-+
|         |- movie_id - int(11) - AUTO_INCREMENT - PRIMARY
|         |- movie_name - varchar(255)
|         |- movie_genres - varchar(255)
|
|         
+- genres-+
          |- genre_id - int(11) - AUTO_INCREMENT - PRIMARY
          |- genre_name - varchar(255)

两个表都包含一些虚拟数据:

+----------+------------+--------------+
| movie_id | movie_name | movie_genres |
+----------+------------+--------------+
|        1 | MOVIE 1    | 2,3,1        |
|        2 | MOVIE 2    | 2,4          |
|        3 | MOVIE 3    | 1,3          |
|        4 | MOVIE 4    | 3,4          |
+----------+------------+--------------+

+----------+------------+
| genre_id | genre_name |
+----------+------------+
|        1 | Comedy     |
|        2 | Fantasy    |
|        3 | Action     |
|        4 | Mystery    |
+----------+------------+

我的目标是得到这样的结果:

+----------+------------+--------------+-----------------------+
| movie_id | movie_name | movie_genres |   movie_genre_names   |
+----------+------------+--------------+-----------------------+
|        1 | MOVIE 1    | 2,3,1        | Fantasy,Action,Comedy |
|        2 | MOVIE 2    | 2,4          | Fantasy,Mystery       |
|        3 | MOVIE 3    | 1,3          | Comedy,Action         |
|        4 | MOVIE 4    | 3,4          | Action,Mystery        |
+----------+------------+--------------+-----------------------+

我正在使用这个查询,它部分有效,唯一的问题是它使用了 IN 值列表中 movie_genres 字段的第一个值。

SELECT `m` . * , GROUP_CONCAT( `g`.`genre_name` ) AS `movie_genre_names`
FROM `genres` AS `g`
LEFT JOIN `movies` AS `m` ON ( `g`.`genre_id`
IN (
`m`.`movie_genres`
) )
WHERE `g`.`genre_id`
IN (
(
SELECT `movie_genres`
FROM `movies`
WHERE `movie_id` =1
)
)
GROUP BY 1 =1

结果与我想要的结果大不相同:

+----------+------------+--------------+-------------------+
| movie_id | movie_name | movie_genres | movie_genre_names |
+----------+------------+--------------+-------------------+
|        1 | MOVIE 1    | 2,3,1        | Fantasy,Fantasy   |
+----------+------------+--------------+-------------------+

对不起,如果我错过了一些数据,我是 mysql 的新手。

我应该使用什么查询来获得想要的结果?

【问题讨论】:

你如何创建这个页面上显示的如此漂亮的表结构。在***中创建表有什么语法吗? 第一个手动,其他通过 mysql shell 【参考方案1】:

这是一个糟糕的设计。您应该创建一个many-to-many 链接表(movie_id, genre_id)

但是,如果您无法更改此设计,请使用此查询:

SELECT  movie.*
        (
        SELECT  GROUP_CONCAT(genre_name)
        FROM    genres
        WHERE   find_in_set(genre_id, movie_genres)
        ) as movie_genre_names
FROM    movies

【讨论】:

谢谢。最终查询如下所示。 SELECT *, (SELECT GROUP_CONCAT(genre_name) FROM genres WHERE FIND_IN_SET(genre_id, movie_genres)) AS movie_genre_names FROM movies;

以上是关于MySQL - 如何按值在 IN 语句中使用子查询的主要内容,如果未能解决你的问题,请参考以下文章

mysql 数据操作 子查询 介绍

Mysql知识补充

MySQL的SQL语句 - 数据操作语句(13)- 子查询(12)

Mysql的查询

MySQL 之子查询

Mysql语句优化