一次从多个表中选择(多对多关系) - MySQL

时间:2011-11-17 16:37:14

标签: mysql database many-to-many

我得到了这些表格:

filminfo:

  • filminfo_id(int)
  • filminfo_author(int)
  • filminfo_title(varchar)
  • filminfo_releaseYear(int)

流派:

  • genre_id(int)
  • genre_name(varchar)

filmGenres:

  • filmGenre_id(int)
  • filmGenre_filmId(int)
  • filmGenre_genreId(int)

用户

  • user_id(int)
  • user_firstname(varchar)
  • user_lastname(varchar)

董事:

  • director_id(int)
  • director_firstname(varchar)
  • director_lastname(varchar)

filmDirectors:

  • filmDirector_id(int)
  • filmDirector_filmId(int)
  • filmDirector_directorId(int)

我想选择以下内容:

  • filminfo_id
  • filminfo_title
  • filminfo_releaseYear
  • genre_name(匹配filmGenres)
  • user_firstname(匹配filminfo_author)
  • user_lastname(匹配filminfo_author)
  • director_firstname(匹配filmDirectors)
  • director_lastname(匹配filmDirectors)

我整天都被困在这里。我喜欢能帮助我解决这个问题的人!

到目前为止我做了什么:

SELECT
f.filminfo_title,
f.filminfo_releaseYear,
u.user_id,
u.user_firstName,
u.user_lastName,
d.director_firstname,
d.director_lastname,
GROUP_CONCAT(g.genre_name SEPARATOR ', ') genre
FROM (filmGenres fg, filmDirectors fd,filmActors fa) 
INNER JOIN filminfo f ON f.filminfo_id = fg.filmGenre_filmId  
INNER JOIN genres g ON g.genre_id = fg.filmGenre_genreId
INNER JOIN users u ON u.user_id = f.filminfo_author
INNER JOIN directors d ON d.director_id = fd.filmDirector_directorId
GROUP BY
f.filminfo_title,
f.filminfo_releaseYear
ORDER BY f.filminfo_releaseYear DESC
LIMIT 0,10;

请帮忙!

<小时/> 修改
我很亲密:

SELECT
    f.filminfo_title,
    f.filminfo_originalTitle,
    f.filminfo_suggestedAge,
    f.filminfo_runtime,
    f.filminfo_releaseYear,
    f.filminfo_description,
    f.filminfo_youtubeId,
    user_firstname,
    user_lastname,
    fi.filmImage_image,
    GROUP_CONCAT(genre_name SEPARATOR ', ') as genrenames,
    GROUP_CONCAT(CONCAT(director_firstname, ' ',
                        director_lastname) SEPARATOR ', ') as directors
FROM filmGenres fg
JOIN filminfo f ON f.filminfo_id = fg.filmGenre_filmId
JOIN users u ON u.user_id = f.filminfo_author
JOIN genres g ON g.genre_id = fg.filmGenre_genreId
JOIN filmDirectors fd ON fd.filmDirector_filmId = f.filminfo_id
JOIN directors d ON d.director_id = fd.filmDirector_directorId
JOIN filmImages fi ON fi.filmImage_id = f.filminfo_id
GROUP BY f.filminfo_title

但这会让董事多次回归(例如:Ridley Scott,Ridley Scott)。我做错了什么?

2 个答案:

答案 0 :(得分:0)

Select 

    fi.filminfo_id,
    fi.filminfo_title,
    fi.filminfo_releaseYear,
    g.genre_name, -- (matching filmGenres)
    u.user_firstname, -- (matching filminfo_author)
    u.user_lastname, -- (matching filminfo_author)
    d.director_firstname, -- (matching filmDirectors)
    d.director_lastname -- (matching filmDirectors)

From filminfo fi, genres g, filmGenres fg, users u, directors d, filmdirectors fd

Where
        fg.filmGenre_filmId  = fi.filminfo_id
    and fd.filmId=fi.filmInfo_id
    and g.genre_id=fg.filmGenre_genreId
    and u.user_id=fi.filminfo_author
    and d.director_id=filmDirector_directorId

如果电影有多种类型,作者或导演,这将为同一部电影返回多行。我没有添加订单,因为回答这个问题似乎无关紧要。

修改

在回答您编辑过的问题时,请添加关键字distinct,以便仅选择不同的行。如果你仍然得到重复的导演名字,那是因为你的数据是这样的,电影有一个导演,但有多个作者或流派。

SELECT DISTINCT
    f.filminfo_title,
    f.filminfo_originalTitle,
    f.filminfo_suggestedAge,
    f.filminfo_runtime,
    f.filminfo_releaseYear,
    f.filminfo_description,
    f.filminfo_youtubeId,
    user_firstname,
    user_lastname,
    fi.filmImage_image,
    GROUP_CONCAT(genre_name SEPARATOR ', ') as genrenames,
    GROUP_CONCAT(CONCAT(director_firstname, ' ',
                        director_lastname) SEPARATOR ', ') as directors
FROM filmGenres fg
JOIN filminfo f ON f.filminfo_id = fg.filmGenre_filmId
JOIN users u ON u.user_id = f.filminfo_author
JOIN genres g ON g.genre_id = fg.filmGenre_genreId
JOIN filmDirectors fd ON fd.filmDirector_filmId = f.filminfo_id
JOIN directors d ON d.director_id = fd.filmDirector_directorId
JOIN filmImages fi ON fi.filmImage_id = f.filminfo_id
GROUP BY f.filminfo_title

答案 1 :(得分:0)

这里的问题是多个导演对电影关系的影响并不是单独输出它们。我也是连任董事:

SELECT
    filmGenre_filmId,
    filminfo_title,
    filminfo_releaseYear,
    user_firstname,
    user_lastname,
    GROUP_CONCAT(genre_name SEPARATOR ', ') as genrenames,
    GROUP_CONCAT(CONCAT(director_firstname, ' ',
                        director_lastname) SEPARATOR ', ') as directors
FROM filmGenres fg
JOIN filminfo f ON filmGenre_filmId = filminfo_id
JOIN users u ON filminfo_author = user_id
JOIN genres g ON filmGenre_genreId = genre_id
JOIN filmDirectors fd ON filmGenre_filmId = filmDirector_filmId
JOIN directors d ON filmDirector_directorId = director_id 
GROUP BY filmGenre_filmId

UPD1:

这是一个简化的查询,需要进行一些优化:

SELECT
    filminfo_id,
    filminfo_title,
    filminfo_releaseYear,
    user_firstname,
    user_lastname,
    genrenames,
    directors
FROM filminfo f
JOIN users u ON filminfo_author = user_id
JOIN (
    SELECT
        filmGenre_filmId,
        GROUP_CONCAT(genre_name SEPARATOR ', ') as genrenames
    FROM filmGenres
    JOIN genres g ON filmGenre_genreId = genre_id
    GROUP BY filmGenre_filmId
) as g ON filminfo_id = filmGenre_filmId
JOIN (
    SELECT
        filmDirector_filmId,
        GROUP_CONCAT(CONCAT(director_firstname, ' ',
                            director_lastname) SEPARATOR ', ') as directors
    FROM filmDirectors
    JOIN directors d ON filmDirector_directorId = director_id
    GROUP BY filmDirector_filmId
) as d ON filminfo_id = filmDirector_filmId