SQL关联user与user_goal表导出仅取用户最新体重的查询修正
原有查询的问题点
- 字段拼写错误:原SQL中写的
ug.weigth和实际表字段weight拼写不一致,本身存在语法错误 - 分组逻辑不符合SQL规范:直接
GROUP BY ug.user_id后查询未被聚合的u.name、ug.weight,在严格SQL模式下会直接报错;就算在非严格模式下能执行,数据库也只会在分组内随机选取一行返回,很多场景下正好命中分组的首条记录,这也是你当前查询返回Joe=111、Bob=120的根本原因,和你要的“最后录入”结果无关 - 缺失核心筛选逻辑:没有定义“最后录入记录”的判断规则——结合你的表数据结构,
user_goal表的自增主键id天然对应录入顺序,越晚录入的记录id越大,每个用户下id最大的行就是最后录入的weight值。
额外提醒:不要直接对weight字段做MAX聚合取值,体重数值大小和录入顺序没有必然关联,比如你提供的示例里Joe最后录入的222,比之前录入的333数值更小,直接取MAX(weight)会返回错误的333结果。
可行的修改方案
方案1:窗口函数(适配主流数据库,MySQL 8.0+、PostgreSQL、SQL Server均可使用)
通过窗口函数给每个用户的goal记录按id倒序排序,直接取排序第一的最新记录,再关联用户表查询结果:
WITH latest_goal AS ( SELECT user_id, weight, ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY id DESC) AS row_rank FROM user_goal ) SELECT u.name, lg.weight FROM user u INNER JOIN latest_goal lg ON u.id = lg.user_id WHERE lg.row_rank = 1
方案2:适配低版本数据库(如MySQL 5.x,不支持窗口函数)
先通过子查询拿到每个用户对应的最新goal记录id,再关联原表和用户表取最终值:
SELECT u.name, ug.weight FROM user u INNER JOIN user_goal ug ON u.id = ug.user_id INNER JOIN ( -- 拿到每个用户id对应的最新goal记录id SELECT user_id, MAX(id) AS latest_goal_id FROM user_goal GROUP BY user_id ) latest ON ug.id = latest.latest_goal_id
以上两种写法的最终返回结果,都和你期望的Joe对应222、Bob对应190完全一致。
内容的提问来源于stack exchange,提问作者Amiga500
相关产品推荐
相关产品推荐

