我正在尝试选择他们对话中最后一个的所有评论。如果注释具有相同的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中工作。
答案 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'。