SQL关联ticket和comments表查询最新updatedAt记录报错解决
报错原因
- 原语句在
WHERE子句中直接使用聚合函数max(c.updatedat)属于语法错误:SQL执行顺序中WHERE过滤早于聚合计算,不能直接在WHERE中引用聚合结果。 - 原逻辑没有按工单维度分组取最新评论,直接匹配全局最大的
updatedat,无法实现「每个工单对应自身最新评论note」的需求。
正确实现方案
方案1:窗口函数写法(推荐,支持MySQL8.0+、PostgreSQL、SQL Server等主流数据库)
先给每个工单下的所有评论按更新时间倒序编号,只取编号为1的最新一条关联工单表:
SELECT t.id, t.title, t.requesterEmail, t.createdAt, c.note, t.priority, t.assigneeEmail, t.status FROM ticket t INNER JOIN ( SELECT *, ROW_NUMBER() OVER(PARTITION BY ticketid ORDER BY updatedat DESC) as rn FROM comments ) c ON c.ticketid = t.id AND c.rn = 1 WHERE t.assigneeEmail = 'bhavya.aggarwal@gmail.com' AND t.status = 'Open';
方案2:聚合子查询关联写法(兼容不支持窗口函数的老版本数据库)
先聚合计算出每个工单对应的最新评论时间戳,再通过时间戳和工单ID关联回评论表取对应的note内容:
SELECT t.id, t.title, t.requesterEmail, t.createdAt, c.note, t.priority, t.assigneeEmail, t.status FROM ticket t INNER JOIN ( SELECT ticketid, MAX(updatedat) as latest_updated FROM comments GROUP BY ticketid ) c_max ON c_max.ticketid = t.id INNER JOIN comments c ON c.ticketid = c_max.ticketid AND c.updatedat = c_max.latest_updated WHERE t.assigneeEmail = 'bhavya.aggarwal@gmail.com' AND t.status = 'Open';
注意:如果单个工单下存在两条
updatedAt完全一致的评论,方案2会返回多条匹配记录。如果使用方案1时需要保留这类重复记录,可以将ROW_NUMBER()替换为RANK();如果只需要返回任意一条最新评论,保持ROW_NUMBER()即可。
内容的提问来源于stack exchange,提问作者user15692170
相关产品推荐
相关产品推荐

