如何筛选customer表gift_type仅为cash且无coupon、discount的客户记录
原SQL错误原因分析
- SQL1的问题:WHERE条件是逐行判断的,仅能筛选出
gift_type为cash的单行记录,无法校验同个客户下的所有礼品类型。如果某客户同时持有cash和coupon类型的两条记录,cash对应的行依然会命中查询条件,导致结果不符合预期。 - SQL2的问题:两张customer表未加关联条件,会生成笛卡尔积,查询逻辑完全不成立,无法实现按客户维度的礼品类型校验。
正确查询方案
方案1:分组聚合校验(逻辑最直观)
按客户ID分组后,通过聚合函数校验全量礼品类型的符合情况:
SELECT cust_id FROM customer GROUP BY cust_id HAVING -- 确保客户至少有1次cash类型的礼品领取记录 COUNT(CASE WHEN gift_type = 'cash' THEN 1 END) > 0 -- 确保客户完全没有coupon、discount类型的领取记录 AND COUNT(CASE WHEN gift_type IN ('coupon', 'discount') THEN 1 END) = 0;
方案2:NOT EXISTS 排除法(性能更优,适合大表场景)
先过滤出持有cash的客户,再排除所有曾领取过其他两类礼品的客户:
SELECT DISTINCT c1.cust_id FROM customer c1 WHERE c1.gift_type = 'cash' AND NOT EXISTS ( SELECT 1 FROM customer c2 WHERE c2.cust_id = c1.cust_id AND c2.gift_type IN ('coupon', 'discount') );
补充简化写法(仅适用于cust_id无空值的场景)
如果确认cust_id字段不存在空值,可以用NOT IN简化逻辑:
SELECT DISTINCT cust_id FROM customer WHERE gift_type = 'cash' AND cust_id NOT IN ( SELECT cust_id FROM customer WHERE gift_type IN ('coupon', 'discount') );
内容的提问来源于stack exchange,提问作者Happy Man
相关产品推荐
相关产品推荐

