MySQL使用Join和Group by后查询结果与实际数据不同步问题
问题原因
- 你的查询写法本身存在逻辑漏洞,核心问题出在非分组、非聚合字段直接出现在SELECT列表中的错误用法:
- 你当前仅按
Till_No分组,但SELECT里除了分组字段Till_No、聚合函数MAX(DateTime)外,剩下的c.Company_Name、Branch_Name、各类日期字段都既不是分组依据,也没有用聚合函数包裹。 - 仅当你的数据库关闭了
ONLY_FULL_GROUP_BYSQL模式时这种写法才不会报错,但数据库不会帮你匹配最大DateTime对应的行的其他字段值,而是会从分组内随机选取一行的对应字段返回,数据量少的时候刚好选中了你预期的行,数据量变大后就会出现匹配错乱的问题。
- 你当前仅按
修正方案
你需要先查询出每个Till_No对应的最大DateTime,再关联原表和Customers表获取对应的其他字段,正确写法参考如下:
SELECT c.Company_Name, c.Branch_Name, t.Till_No, t.Database_Build_Date, t.Database_Updated_Date, t.Touchkeys_Build_Date, t.Touchkeys_Updated_Date, t_max.max_datetime FROM ( -- 先取每个Till_No对应的最大日期 SELECT Till_No, MAX(DateTime) AS max_datetime FROM `TillDatabase` WHERE ClientID = 1 AND Branch = 1 GROUP BY Till_No ) AS t_max -- 关联原表拿到最大日期对应的整行数据 INNER JOIN `TillDatabase` t ON t.Till_No = t_max.Till_No AND t.DateTime = t_max.max_datetime AND t.ClientID = 1 AND t.Branch = 1 -- 关联客户表取名称字段 INNER JOIN Customers c USING(ClientID, Branch) ORDER BY t.Till_No ASC;
如果你的数据库支持窗口函数(MySQL 8.0+、MariaDB 10.2+等),也可以用ROW_NUMBER写法更简洁:
SELECT Company_Name, Branch_Name, Till_No, Database_Build_Date, Database_Updated_Date, Touchkeys_Build_Date, Touchkeys_Updated_Date, DateTime FROM ( SELECT c.Company_Name, c.Branch_Name, t.Till_No, t.Database_Build_Date, t.Database_Updated_Date, t.Touchkeys_Build_Date, t.Touchkeys_Updated_Date, t.DateTime, -- 按Till_No分组,日期倒序排,序号1就是最新的行 ROW_NUMBER() OVER (PARTITION BY t.Till_No ORDER BY t.DateTime DESC) AS rn FROM `TillDatabase` t INNER JOIN Customers c USING(ClientID, Branch) WHERE t.ClientID = 1 AND t.Branch = 1 ) AS tmp WHERE rn = 1 ORDER BY Till_No ASC;
内容的提问来源于stack exchange,提问作者Dave Hamilton
相关产品推荐
相关产品推荐

