如何在SELECT语句中使用HAVING子句并合并相似查询实现多维度商家客户交易统计
合并两条相似SQL查询为一条的解决方案
这问题很典型,其实我们可以通过条件聚合+子查询预分组的方式,把两个统计字段合并到同一条SQL里,既减少重复代码,还能提升查询效率。直接给你最终的实现语句:
SELECT b.name, COUNT(user_grouped.user_id) AS the_number_of_unique_customers_num, SUM(CASE WHEN user_grouped.transaction_count > 1 THEN 1 ELSE 0 END) AS the_number_of_unique_customers_have_had_more_than_one_trans FROM businesses b LEFT JOIN ( -- 先预统计每个用户在对应商家的交易次数 SELECT business_id, user_id, COUNT(*) AS transaction_count FROM transactions GROUP BY business_id, user_id ) AS user_grouped ON b.id = user_grouped.business_id GROUP BY b.id, b.name;
逻辑拆解:
- 内层子查询
user_grouped:先按business_id和user_id分组,统计每个用户在每个商家的交易总次数,这样我们就得到了每个商家下所有用户的交易频次数据。 - 关联主表并聚合:把这个预分组的结果和
businesses表关联,然后:COUNT(user_grouped.user_id):直接统计每个商家下的唯一用户数(因为子查询已经按用户分组,所以每一行对应一个唯一用户)SUM(CASE WHEN ...):用条件判断,把交易次数>1的用户标记为1,否则0,最后求和就得到了每个商家下交易次数超过1的用户数量。
结果验证
这条语句执行后,会直接输出你期望的结果:
+------+------------------------------------+-------------------------------------------------------------+ | name | the_number_of_unique_customers_num | the_number_of_unique_customers_have_had_more_than_one_trans | +------+------------------------------------+-------------------------------------------------------------+ | foo | 2 | 1 | | bar | 1 | 1 | | baz | 1 | 0 | +------+------------------------------------+-------------------------------------------------------------+
相比你原来的两个嵌套子查询,这种方式只需要对transactions表做一次分组扫描,性能更优,代码也更易读维护。
内容的提问来源于stack exchange,提问作者stack
相关产品推荐
相关产品推荐

