【问题标题】:MYSQL, Max,Group by and MaxMYSQL、Max、Group by 和 Max
【发布时间】:2013-03-28 10:50:56
【问题描述】:

我有以下两个表。

1.Movie Detail(Movie-ID、Movie_Name、Rating、Votes、Year)

2.电影类型(Movie-ID,Genre)

我正在使用以下查询来执行连接并获取每个中评分最高的电影 流派。

select Movie_Name, 
    max(Rating) as Rating,
    Genre from movie_test 
inner join movie_genre 
where movie_test.Movie_ID = movie_genre.Movie_ID 
group by Genre

在输出中,Rating 和 Genre 正确,但 Movie_Name 不正确。

谁能建议我应该进行哪些更改才能获得正确的电影名称以及评级和类型。

【问题讨论】:

  • JOINs 使用 ON 而不是 WHERE
  • @DreamEater 在 mysql 中,已被接受。

标签: mysql sql greatest-n-per-group


【解决方案1】:
SELECT  g.*, d.*
FROM    MovieGenre g
        INNER JOIN MovieDetail d
            ON g.MovieID = d.MovieID
        INNER JOIN
        (
            SELECT  a.Genre, MAX(b.Rating) maxRating
            FROM    MovieGenre a
                    INNER JOIN MovieDetail b
                        ON a.MovieID = b.MovieID
            GROUP   BY a.Genre
        ) sub ON    g.Genre = sub.Genre AND
                    d.rating = sub.maxRating

您的架构设计有问题。如果一个Movie 可以有多个Genre 并且Genre 可以包含在多个Movie 上,那么它应该是一个三表设计。

电影详情表

  • 电影 ID (PK)
  • 电影名
  • MovieRating

类型表

  • 类型 ID (PK)
  • 流派名称

电影类型表

  • MovieID (FK) -- 带有 GenreID 的复合主键
  • 流派 ID (FK)

【讨论】:

  • 查询是否正常?我有一个问题要问你,一部电影可以有多种流派吗?流派可以包含在许多电影中吗?还是一部电影只能有一种类型?
  • 我一部电影可以有多个流派。我已经通过了你的ans。感谢您帮助我改进架构设计。查询运行良好
  • @Jack 如果是这种情况,那么您可以使用我建议的设计重构表格。
  • 是的,我肯定会重组我的设计。感谢您的建议
【解决方案2】:

这是一个常见的 MySQL 问题 - 在聚合查询中指定非聚合/非聚合列。其他风格的 SQL 不允许您这样做,并且会警告您。 p>

当您执行类似的查询时,您选择的是聚合组中的非聚合列。由于许多行共享相同的类型,因此当您选择 Movie_Name 时,它会从每个组中随机选择一行并显示该行,因为没有通用算法来猜测您想要的行并返回该行的值。

您可能会问“为什么它会随机选择?它可以选择 max(Rating) 所属的那个吗?但是其他聚合列呢,比如 avg(Rating)?它在那里选择哪一行?无论如何,如果两行具有相同的最大值怎么办?因此它不能有一个算法来选择一行。

要解决这样的问题,您必须重组查询,例如:

select Movie_Name, 
    Rating,
    Genre from movie_test mt
inner join movie_genre 
where movie_test.Movie_ID = movie_genre.Movie_ID 
and Rating = (select max(Rating) from movie_test mt2 where mt.Genre = mt2.Genre
group by Genre
limit 1

这将使用子查询选择评级与该类型的最高评级相同的行。

【讨论】:

    【解决方案3】:

    查询:

    SELECT t.Movie_Name,
           t.Rating,
           g.Genre
    FROM movie_test t
    INNER JOIN movie_genre g ON t.Movie_ID = g.Movie_ID
    WHERE t.Movie_ID = (SELECT t1.Movie_ID 
                        FROM movie_test t1
                        INNER JOIN movie_genre g1 ON t1.Movie_ID = g1.Movie_ID
                        WHERE g1.Genre = g.Genre
                        ORDER BY t1.Rating DESC
                        LIMIT 1)
    

    【讨论】:

      猜你喜欢
      • 2022-01-04
      • 1970-01-01
      • 2018-06-29
      • 2021-12-26
      • 1970-01-01
      • 2011-08-05
      • 2010-11-20
      • 2012-10-30
      相关资源
      最近更新 更多