使用group by和order by进行sql查询时出现问题

时间:2011-01-10 16:36:27

标签: sql mysql sqlite

我正在尝试选择他们对话中最后一个的所有评论。如果注释具有相同的object_id和type_id,则它们位于同一对话中。这是我现在的查询:

select * from comments 
 where user_id != #{current_user.id} 
 group by type_id, object_id 
 order by created_at desc

除了评论并不总是对话中的最后一个,它才有效。我怎样才能做到这一点?我需要它在mysql和sqlite3中工作。

5 个答案:

答案 0 :(得分:1)

此查询不是很漂亮(在您的服务器上运行可能非常慢),但是......

SELECT 
    MAX(created_at) created_at,
    * 
FROM 
    comments 
WHERE 
    user_id != #{current_user.id} 
GROUP BY 
    type_id, 
    object_id 
ORDER BY
    created_at DESC
编辑:注意到这不起作用。需要的是用于解决此问题的表模式。

答案 1 :(得分:1)

如果您遇到组合问题首先要做的就是避免使用'*'。这是MySQL提供的标准GROUP BY of SQL的扩展。

Classic group by必须包含select中使用的所有非聚合列。 mySQl让你避免了这个非常基本的事实,并对结果有一些随机性:

  

类似的MySQL扩展适用于   HAVING子句。 SQL标准   不允许使用HAVING子句   命名在GROUP中找不到的任何列   BY子句如果没有包含在   集合函数。 MySQL允许   使用这些列来简化   计算。 此扩展假设   非编号列将具有   相同的群体价值观。除此以外,   结果是不确定的

因此,请使用普通选择尝试更新版本的查询。

答案 2 :(得分:0)

这是猜测,但需要有关您的架构的更多信息才能确定。您是否需要/只想要最后一条评论,或者您是否尝试按“对话”找到最后的 n 条评论?

  SELECT *
    FROM comments
   WHERE user_id != ...
ORDER BY type_id,
         object_id,
         created_at DESC

答案 3 :(得分:0)

仅使用GROUP BY查询无法获得所需的结果。原因是没有办法指示RDBMS选择与GROUPed集中最后一条注释相对应的注释文本。

而是这样做:

 SELECT * FROM comments 
  WHERE user_id != #{current_user.id} AND created_at = 
    (SELECT MAX(created_at) FROM comments WHERE user_id != #{current_user.id} )

 SELECT * FROM comments c1
  WHERE user_id != #{current_user.id} AND NOT EXISTS
    (SELECT * FROM comments c2 
      WHERE user_id != #{current_user.id} AND c2.created_at > c1.created_at )

(我使用了comment_id,因为它不清楚什么标识注释,但如果它是object_id则使用它而不是)。

答案 4 :(得分:0)

如果要选择每个type_id和object_id组中的最后一条注释,请使用子查询:

select c1.*
from comments c1
join (
  select type_id, object_id, max(created_at) last_comment_created_at
  from comments
  where user_id != #{current_user.id} /* indicates 'comment'? */
  group by type_id, object_id
) c2
on c2.type_id = c1.type_id
  and c2.object_id = c1.object_id
  and c2.last_comment_created_at = c1.created_at

除非有多个注释具有完全相同的type_id,object_id和created_at'值,否则这是有效的。因此,如果有一个像'comment_order'这样的列,则优于'created_at'。