来自JOIN和GROUP_CONCAT的三个表的意外结果

时间:2015-10-18 14:54:03

标签: mysql inner-join group-concat

这是一个指向架构和sql的链接:http://sqlfiddle.com/#!9/d99b6/8

架构:

create table movies (
  id int,
  movie_name varchar(20)
  );

create table genre (
  movie_id int,
  genre varchar(20)
  );

create table actors (
  movie_id int,
  actor_name varchar(20)
  );

insert into movies (id, movie_name)
  values
    (1, 'asdf');

insert into genre (movie_id, genre)
  values
    (1, 'Comedy'),
    (1, 'Thriller');

insert into actors (movie_id, actor_name) 
  values
    (1, 'actor1'),
    (1, 'actor2');

SQL:

select movies.id,
  movies.movie_name,
  group_concat(genre.genre separator ', ') as genre,
  group_concat(actors.actor_name separator ', ') as actors
from movies
inner join genre on genre.movie_id = movies.id
inner join actors on actors.movie_id = movies.id;

我想输出这个:

id    movie_name    genre               actors
1     asdf          Comedy, Thriller    actor1, actor2

但请改为:

id    movie_name    genre                                 actors
1     asdf          Comedy, Thriller, Comedy, Thriller    actor1, actor1, actor2, actor2

不确定如何解决这个问题,请帮助。

2 个答案:

答案 0 :(得分:0)

您可以使用`distinct:

select m.id, m.movie_name,
       group_concat(distinct g.genre separator ', ') as genres,
       group_concat(distinct a.actor_name separator ', ') as actors
from movies m inner join
     genre g
     on g.movie_id = m.id inner join
     actors a
     on a.movie_id = m.id
group by m.id;

如果每部电影都有大量数据,则distinct会增加额外开销。 join为每部电影做了类型和演员的笛卡尔积。您可以通过预聚合或使用相关子查询来处理:

select m.id, m.movie_name,
       (select group_concat(g.genre separator ', ')
        from genre g
        where g.movie_id = m.id 
       ) as genres,
       (select group_concat(a.actor_name separator ', ')
        from actors a
        where a.movie_id = m.id
       ) as actors
from movies m;

答案 1 :(得分:0)

只需添加DISTINCT

select movies.id,
  movies.movie_name,
  group_concat(DISTINCT genre.genre separator ', ') as genre,
  group_concat(DISTINCT actors.actor_name separator ', ') as actors
from movies
inner join genre on genre.movie_id = movies.id
inner join actors on actors.movie_id = movies.id;

SqlFiddleDemo