MySQL查询求助:关联Asset与Inventory表获取最新日期结果异常
问题排查与修复方案
咱们来拆解下你的MySQL查询为什么不符合预期,以及对应的修复方法:
1. 非聚合列的取值不确定性
在标准SQL规则(以及开启了ONLY_FULL_GROUP_BY模式的MySQL)里,SELECT子句中的列要么必须出现在GROUP BY分组字段里,要么得用聚合函数(比如MAX()、MIN())包裹。
你的查询里:
a.user既不在GROUP BY的字段列表里,也没有被聚合函数处理b.note同样不符合这个规则
如果MySQL关闭了ONLY_FULL_GROUP_BY,虽然不会报错,但这两个字段的返回值是随机的——MySQL会从分组内的任意一条记录里取对应值,这肯定不是你想要的结果。
2. 无法关联最新盘点日期对应的备注
你用MAX(b.invdate)拿到了每个资产的最新盘点日期,但b.note并没有和这个最新日期绑定,它可能来自该资产任意一条盘点记录的备注,而不是最新那次盘点的备注。
修复后的查询写法
如果你想要每个资产的基础信息(编号、描述、使用者),加上该资产最新盘点的日期和对应备注,可以用以下两种方法:
方法一:子查询筛选最新记录
SELECT a.assetnum, a.description, a.user, b.invdate, b.note FROM asset a LEFT JOIN ( -- 先筛选出每个资产的最新盘点记录 SELECT assetnum, invdate, note FROM inventory WHERE (assetnum, invdate) IN ( SELECT assetnum, MAX(invdate) FROM inventory GROUP BY assetnum ) ) b ON a.assetnum = b.assetnum;
方法二:窗口函数(MySQL 8.0及以上版本支持)
用窗口函数可以更简洁地实现需求,为每个资产的盘点记录按日期倒序排序,取第一条就是最新的:
SELECT a.assetnum, a.description, a.user, b.invdate, b.note FROM asset a LEFT JOIN ( SELECT assetnum, invdate, note, -- 按资产编号分组,按盘点日期倒序排,给每条记录标序号 ROW_NUMBER() OVER (PARTITION BY assetnum ORDER BY invdate DESC) AS rn FROM inventory ) b ON a.assetnum = b.assetnum AND b.rn = 1;
这两种写法都能确保你拿到最新盘点记录的备注,同时a.user也能正确返回(因为每个assetnum在asset表里对应唯一的使用者)。
内容的提问来源于stack exchange,提问作者GagakAngkasa
相关产品推荐
相关产品推荐

