在列上分组行并展平其他列

时间:2014-01-29 08:37:29

标签: mysql sql group-by group-concat

我有以下架构:

TABLE            ATTRIBUTES
---------------------------
movies           id
                 title

stars            id
                 first_name
                 last_name

genres           id
                 name

stars_in_movies  movie_id
                 star_id

genres_in_movies movie_id
                 genre_id

我想创建一个查询,该查询返回按movie.id分组的视图,该视图连接关联的starsgenres

列表

这是我的尝试:

SELECT movies.id, title,
GROUP_CONCAT(stars.id separator ',') AS starIds,
GROUP_CONCAT(concat(first_name,' ',last_name) separator ',') AS starNames,
GROUP_CONCAT(genres.id separator ',') AS genreIds,
GROUP_CONCAT(genres.name separator ',') AS genreNames
FROM movies 
JOIN stars_in_movies ON stars_in_movies.movie_id = movies.id
JOIN stars ON stars_in_movies.star_id = stars.id
JOIN genres_in_movies ON genres_in_movies.movie_id = movies.id
JOIN genres ON genres_in_movies.genre_id = genres.id

出于某种原因,对于视图中的每一行,查询会为每个类型连接相同的星形。例如,这是一行的示例:

movie.id   movie.title      stars.id      genres.id
-----------------------------------------------------------
12345      Ocean's Twelve   3,3,3,4,4,4   2,4,6,2,4,6,2,4,6

编辑:

这是不使用GROUP_CONCAT的查询结果。它列出了元组的所有组合。

SELECT movies.id, stars.id, genres.id FROM movies
JOIN stars_in_movies ON stars_in_movies.movie_id = movies.id
JOIN stars ON stars_in_movies.star_id = stars.id
JOIN genres_in_movies ON genres_in_movies.movie_id = movies.id
JOIN genres ON genres_in_movies.genre_id = genres.id
WHERE movies.title = 'Oceans Twelve';

+--------+--------+--------+
|movies.id|stars.id|genres.id|
+--------+--------+--------+
| 764010 | 492108 | 907000 |
| 764010 | 492108 | 907001 |
| 764010 | 492108 | 855203 |
| 764010 | 492108 | 907002 |
| 764010 | 492108 | 150008 |
| 764010 | 492108 | 907005 |
| 764010 |  48004 | 907000 |
| 764010 |  48004 | 907001 |
| 764010 |  48004 | 855203 |
| 764010 |  48004 | 907002 |
| 764010 |  48004 | 150008 |
| 764010 |  48004 | 907005 |
| 764010 |  48014 | 907000 |
| 764010 |  48014 | 907001 |
| 764010 |  48014 | 855203 |
| 764010 |  48014 | 907002 |
| 764010 |  48014 | 150008 |
| 764010 |  48014 | 907005 |
| 764010 | 855108 | 907000 |
| 764010 | 855108 | 907001 |
| 764010 | 855108 | 855203 |
| 764010 | 855108 | 907002 |
| 764010 | 855108 | 150008 |
| 764010 | 855108 | 907005 |
| 764010 | 658011 | 907000 |
| 764010 | 658011 | 907001 |
| 764010 | 658011 | 855203 |
| 764010 | 658011 | 907002 |
| 764010 | 658011 | 150008 |
| 764010 | 658011 | 907005 |
| 764010 | 855106 | 907000 |
| 764010 | 855106 | 907001 |
| 764010 | 855106 | 855203 |
| 764010 | 855106 | 907002 |
| 764010 | 855106 | 150008 |
| 764010 | 855106 | 907005 |
| 764010 | 693109 | 907000 |
| 764010 | 693109 | 907001 |
| 764010 | 693109 | 855203 |
| 764010 | 693109 | 907002 |
| 764010 | 693109 | 150008 |
| 764010 | 693109 | 907005 |
+--------+--------+--------+

3 个答案:

答案 0 :(得分:1)

看起来stars_in_movies和genres_in_movies之间存在多对多的关系。您需要逐步执行查询。首先创建一个子集查询,对电影JOIN genres_in_movies进行分组。然后创建第二个子查询,对电影JOIN stars_in_movies进行分组。然后在movie.id上的子查询之间加入。 这样,您就可以在子查询之间建立一对一的关系,从而避免使用当前拥有的笛卡尔积。

答案 1 :(得分:0)

将GROUP BY movies.id,title添加到查询中。

答案 2 :(得分:0)

您的查询几乎完全正确,您只需要添加其他分组(按顺序将这些ID设置为唯一):movies.idstars.idgenres.id

/* YOUR QUERY */
GROUP BY movies.id, stars.id, genres.id