2013-03-28 152 views
1

我有以下兩個表。MYSQL,Max,Group by和最大

1.Movie詳細信息(電影-ID,MOVIE_NAME,評級,票,年)

2.Movie體裁(電影-ID,類型)

我使用下面的查詢來執行加入和在每個 類型中獲得最高評級的電影。

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是不正確的。

任何人都可以建議我應該做什麼改變,以獲得正確的電影名稱與評級和流派。

+0

的'JOIN's使用'ON'而不是'WHERE'。 – hjpotter92 2013-03-28 10:53:03

+0

@DreamEater在MySQL中,它被接受。 – 2013-03-28 10:53:57

回答

3
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,它應該是一個三表設計。

MovieDetails表

  • MovieID(PK)
  • 的movieName
  • MovieRating

流派表

  • GenreID(PK)
  • GenreName

表MOVIE_GENRE

  • MovieID(FK) - 與GenreID
  • GenreID(FK)化合物主鍵
+0

感謝您的回覆。 – Jack 2013-03-28 11:01:53

+0

查詢是否正常工作?我有一個問題給你,單電影可以有多種類型以及體裁可以包含在許多電影?或者一部電影只能有一種風格? – 2013-03-28 11:03:25

+0

我單電影可以有多種流派。我已經通過你的答案。感謝您幫助我改進模式設計。查詢工作正常 – Jack 2013-03-28 11:06:11

0

這是一個常見的MySQL問題 - 指定非聚合/非聚合合作伙伴聚合查詢中的列。其他風格的SQL不會讓你這樣做,並會警告你。

當您執行類似於您的查詢時,您正在選擇聚合組中的非聚合列。由於許多行共享相同的流派,因此當您選擇Movie_Name時,它會從每個組中隨機選取一行並顯示該行,因爲沒有通用算法來猜測所需的行並返回該行的值。

你可能會問'爲什麼它會隨機挑選?它可以選擇最大(評級)所屬的那個?'但其他聚合列如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 

這將選擇與等級是一樣的最大額定值爲體裁的行,使用子查詢。

0

查詢:

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)