SQL中如何对比同交易ID的price总和与行amount值并筛选不等记录
SQL实现方案
已知前提
payment表字段包含id、price、amount、transactionid,示例数据如下:
id, price, amount, transactionid 1, 5, 10, abc 2, 5, 10, abc 3, 20, 40, def 4, 20, 40, def 5, 15, 40, xyz 6, 20, 40, xyz
筛选规则:按transactionid分组计算组内price总和,返回总和与组内单行amount值不相等的所有记录。示例中xyz分组price总和为35,和组内amount值40不等,属于目标结果。
原有基础聚合SQL仅能返回分组汇总值,无法关联组内行数据做比对,以下是两种可直接运行的实现写法:
写法1:窗口函数(推荐)
用窗口函数直接为每行计算所属分组的price总和,避免多表关联,写法更简洁,兼容MySQL8.0+、PostgreSQL、SQL Server等支持窗口函数的数据库:
SELECT * FROM ( SELECT *, SUM(price) OVER (PARTITION BY transactionid) AS group_price_sum FROM payment ) tmp WHERE group_price_sum != amount;
写法2:子查询关联(兼容老版本SQL)
如果使用不支持窗口函数的旧版数据库(比如MySQL5.x),可以先聚合算出每个分组的price总和,再关联原表做筛选:
SELECT p.* FROM payment p INNER JOIN ( SELECT transactionid, SUM(price) AS group_price_sum FROM payment GROUP BY transactionid ) agg ON p.transactionid = agg.transactionid WHERE agg.group_price_sum != p.amount;
执行结果说明
针对给出的示例数据,两种写法返回结果一致,均为transactionid=xyz对应的两条记录:
| id | price | amount | transactionid |
|---|---|---|---|
| 5 | 15 | 40 | xyz |
| 6 | 20 | 40 | xyz |
其余两个分组:abc分组price总和为10,和组内amount值相等;def分组price总和为40,和组内amount值相等,均会被过滤。
内容的提问来源于stack exchange,提问作者dever
相关产品推荐
相关产品推荐

