2012-02-06 46 views
0

我有一個名爲MySQL表「意見」:獲得在MySQL組排好BY查詢

id | date  | movie_id | comment_value 
1 2011/11/05 10   comment_value_1 
2 2012/01/10 10   comment_value_2 
3 2011/10/10 15   comment_value_3 
4 2011/11/20 15   comment_value_4 
5 2011/12/10 30   comment_value_5 

我嘗試有最新的每部電影與查詢評論:

SELECT MAX(date),id,date,movie_id,comment_value FROM comments GROUP BY movie_id 

MAX(日期)返回最近的日期,但相關的行(movie_id,id,comment_value,date)不匹配。它返回影片的第一個評論的價值,就像這樣:

MAX(date) | id | date  | movie_id | comment_value 
2012/01/10 1 2011/11/05 10   comment_value_1 
2011/11/20 3 2011/10/10 15   comment_value_3 
2011/12/10 5 2011/12/10 30   comment_value_5 

所以,我的問題是:我怎麼能有最新的每部電影評論,在只有一個查詢(我實際使用第二個查詢得到好評)

+0

您每個日期的每部電影只有一條評論嗎?如果在同一天有多部電影評論,關係如何被打破,或者你想要他們全部?您可能需要考慮完整的DATETIME列而不是DATE列。 – 2012-02-06 14:22:39

+0

是的,我每個日期的每部電影只有一條評論。 – JuSchz 2012-02-06 14:26:04

回答

4

使用兩個查詢並不是那麼糟糕。否則,你可以這樣做

SELECT id, date, movie_id, comment_value FROM comments c JOIN 
(SELECT movie_id, MAX(date) date FROM comments GROUP BY movie_id) x 
ON x.movie_id=c.movie_id AND x.date=c.date GROUP BY movie_id; 
+0

是否最後一組是必要的? – 2012-02-06 14:17:52

+0

@jules,一定要檢查tpolyak更好的答案。 – 2012-02-06 14:42:50

+0

@ThitLwinOo好點。不,它不是。 – 2012-02-06 14:54:48

3

試試這個:

SELECT c1.* 
FROM comments c1 
LEFT JOIN comments c2 ON (c1.movie_id = c2.movie_id AND c1.date < c2.date) 
WHERE c2.id IS NULL 

由於連接條件就可以加入只有不包含的最大日期值的行,所以過濾具有c2.id IS NULL的行爲您提供具有最大值的行。

+0

+1這是本書[SQL Antipatterns]推薦的方法(http://pragprog.com/book/bksqla/sql-antipatterns),比使用子查詢更容易優化。 – 2012-02-06 14:33:06

+0

我明白這個想法,但是當我執行查詢時,我的行沒有按movie_id分組。 – JuSchz 2012-02-06 14:52:55

+0

如果這是您想要的,您仍然必須添加「GROUP BY movie_id」。 – 2012-02-06 14:54:19

-1

是否可以使用DATETIME字段而不是DATE?這將使查詢變得更容易,並提供更好的報告功能。如果需要,您始終可以將DATETIME字段彙總爲更具體的內容。

+0

是的,它可以使用DATETIME。但我不明白它有什麼不同。你能解釋更多嗎? – JuSchz 2012-02-06 14:17:32

+0

DATETIME包含時間(下降到毫秒)。所以,當從評論中做SELECT MAX(日期)時,您將始終得到最新的評論。 – HubblyJubbly 2012-02-06 18:22:02

0
create table comments (id int,movie_dt datetime,movie_id int,comment_value nvarchar(100)) 

insert into comments values (1,'2011/11/05',10,'comment_value_1') 
insert into comments values (2,'2012/01/10',10,'comment_value_2') 
insert into comments values (3,'2011/10/10',15,'comment_value_3') 
insert into comments values (4,'2011/11/20',15,'comment_value_4') 
insert into comments values (5,'2011/12/10',30,'comment_value_5') 

select a.id, m.movie_dt, m.movie_id,a.comment_value 
from comments a 
inner join 
(
    SELECT MAX(movie_dt) movie_dt,movie_id 
    FROM comments 
    GROUP BY movie_id 
) m on (a.movie_dt = m.movie_dt and a.movie_id = m.movie_id)