2012-02-06 44 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)