如何通过嵌套SQL查询识别余额变动异常且与历史平均值不符的账户?
- 内容介绍
- 相关推荐
本文共计944个文字,预计阅读时间需要4分钟。
直接结论:
为什么嵌套查询查余额异常容易出错
典型写法是外层查每笔交易,内层用 (SELECT AVG(amount) FROM transactions t2 WHERE t2.account_id = t1.account_id) 算历史均值——但问题在于:
- MySQL 5.7 默认开启
sql_mode=ONLY_FULL_GROUP_BY,若外层没加GROUP BY却在SELECT里混用聚合和非聚合字段,直接报错Expression #1 of SELECT list is not in GROUP BY clause - 子查询里引用外层别名(如
t1.account_id)时,某些旧版 MySQL 不支持相关子查询的“向上可见”,返回空结果而非报错,静默出错 - 对每个账户每条记录都执行一次子查询,数据量过万后性能断崖式下降
用窗口函数替代嵌套查询(推荐)
核心思路:先按 account_id 分组计算历史平均变动额,再与当前单笔 amount 比较。
本文共计944个文字,预计阅读时间需要4分钟。
直接结论:
为什么嵌套查询查余额异常容易出错
典型写法是外层查每笔交易,内层用 (SELECT AVG(amount) FROM transactions t2 WHERE t2.account_id = t1.account_id) 算历史均值——但问题在于:
- MySQL 5.7 默认开启
sql_mode=ONLY_FULL_GROUP_BY,若外层没加GROUP BY却在SELECT里混用聚合和非聚合字段,直接报错Expression #1 of SELECT list is not in GROUP BY clause - 子查询里引用外层别名(如
t1.account_id)时,某些旧版 MySQL 不支持相关子查询的“向上可见”,返回空结果而非报错,静默出错 - 对每个账户每条记录都执行一次子查询,数据量过万后性能断崖式下降
用窗口函数替代嵌套查询(推荐)
核心思路:先按 account_id 分组计算历史平均变动额,再与当前单笔 amount 比较。

