【问题标题】:Select from many tables at once (many to many relations) - MySQL一次从多个表中选择(多对多关系) - MySQL
【发布时间】:2011-11-18 17:26:26
【问题描述】:

我有这些表:

电影信息:

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

类型:

  • genre_id (int)
  • genre_name (varchar)

电影流派:

  • 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)

电影导演:

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

我想选择以下:

  • filminfo_id
  • 电影信息标题
  • filminfo_releaseYear
  • 流派名称(匹配电影流派)
  • user_firstname(匹配 filminfo_author)
  • user_lastname(匹配 filminfo_author)
  • director_firstname(匹配电影导演)
  • director_lastname(匹配电影导演)

我一整天都被这个问题困扰着。我喜欢能帮我解决这个问题的人!

到目前为止我做了什么:

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)。我做错了什么?

【问题讨论】:

  • 您发布的代码有什么问题?结果怎么不符合你的预期?
  • 我已经编辑了我的第一篇文章。最后一条 SQL 有效,但它重复了导演姓名。这快把我逼疯了!
  • 我已经编辑了我的答案,看看吧! :)

标签: mysql database many-to-many


【解决方案1】:
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

【讨论】:

    【解决方案2】:

    这里的问题是,由于多个导演与电影的关系,单独输出它们没有意义。我也连接了导演:

    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
    

    【讨论】:

    • 关闭,但仍然无法正常工作。检查我的“编辑”,你会明白为什么。
    • @evenaug,你是对的,我使用了错误的分组列。我编辑了查询并添加了另一个查询,它应该可以工作,但根据您的 filminfo 表的大小,可能不会很好。
    猜你喜欢
    • 2017-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-01
    • 1970-01-01
    • 2017-10-17
    • 1970-01-01
    相关资源
    最近更新 更多