SQL用INNER JOIN和COUNT DISTINCT统计活跃用户各类型交易数
解决方案
你要的统计逻辑可以直接通过关联表加分组聚合实现,不需要用COUNT(DISTINCT),之前结果不对大概率是误用了去重计数,或者分组/筛选条件写的位置不对。
写法1:INNER JOIN 实现(最容易理解,适合入门)
SELECT t.TransactionType, COUNT(*) AS `Count` FROM Transactions t INNER JOIN Users u ON t.UserID = u.UserID WHERE u.State = 'Active' GROUP BY t.TransactionType;
逻辑说明:
- 用
INNER JOIN通过UserID关联两张表,自动排除没有匹配用户信息的交易记录 WHERE条件直接过滤出状态为Active的用户对应的所有交易,这里会直接排除UserID=300的非活跃用户的1条Grocery交易- 按
TransactionType分组后,用COUNT(*)统计每个交易类型下的总记录数,就是对应交易的总笔数
写法2:EXISTS 实现(大表场景性能更优)
如果Transactions表数据量很大,用EXISTS半连接的写法效率更高,不需要做全量两表关联,只需要校验交易对应的用户是活跃状态即可:
SELECT TransactionType, COUNT(*) AS `Count` FROM Transactions t WHERE EXISTS ( SELECT 1 FROM Users u WHERE u.UserID = t.UserID AND u.State = 'Active' ) GROUP BY TransactionType;
常见错误说明
你之前用COUNT(DISTINCT)没得到正确结果,是因为这个函数是用来统计去重后的唯一值数量的:
- 如果写
COUNT(DISTINCT t.UserID),统计的是发生某类交易的活跃用户数,不是交易笔数 - 如果错误加了交易类型、用户ID的去重逻辑,会把同一用户的多笔同类型交易合并计数,结果就会和预期不符
执行上述任意一段SQL,都会得到你期望的结果:
| TransactionType | Count |
|---|---|
| Gas | 3 |
| Grocery | 2 |
内容的提问来源于stack exchange,提问作者FlyingPickle
相关产品推荐
相关产品推荐

