如何编写SQL查询用户符合资格的可使用折扣?
解决按顺序获取用户符合资格折扣的问题
我来帮你梳理完整的解决方案——你的开头思路是对的,但核心是要精准筛选出用户当前按规则应该使用的下一个折扣,而不是所有未使用的折扣毕竟用户必须严格按Position顺序使用,符合资格的其实是「已使用折扣的最大Position值+1」对应的那一条(或对应每个商家的那一条)。
步骤拆解
- 第一步:确定用户的“下一个资格Position”
先统计用户在每个商家已使用折扣的最大Position值,如果用户还没在该商家用过任何折扣,这个值会是NULL,我们可以用COALESCE()把它转成0,加1后正好对应第一个折扣的Position(1)。 - 第二步:匹配对应折扣
把商家的Discounts表和第一步算出的“资格Position”关联,就能拿到用户当前符合条件的折扣。
具体SQL示例
假设你的表结构如下:
Business:business_id(主键)Discounts:discount_id,business_id(关联Business),position,discount_info(其他折扣字段)UsedDiscounts:used_id,user_id,discount_id(关联Discounts)
通用版(查询用户在所有商家的符合资格折扣)
SELECT d.* FROM Discounts d JOIN ( -- 统计用户已使用的最大Position,计算下一个资格Position SELECT COALESCE(MAX(d_inner.position), 0) + 1 AS eligible_pos, d_inner.business_id FROM UsedDiscounts ud JOIN Discounts d_inner ON ud.discount_id = d_inner.discount_id WHERE ud.user_id = '目标用户ID' -- 替换为实际用户ID GROUP BY d_inner.business_id -- 补充处理用户完全没使用过某商家折扣的情况 UNION ALL SELECT 1 AS eligible_pos, b.business_id FROM Business b WHERE NOT EXISTS ( SELECT 1 FROM UsedDiscounts ud JOIN Discounts d_inner ON ud.discount_id = d_inner.discount_id WHERE ud.user_id = '目标用户ID' AND d_inner.business_id = b.business_id ) ) eligible_list ON d.business_id = eligible_list.business_id AND d.position = eligible_list.eligible_pos;
简化版(仅查询单个商家的符合资格折扣)
如果只需要针对某一个商家查询,SQL可以更简洁:
SELECT d.* FROM Discounts d WHERE d.business_id = '目标商家ID' AND d.position = ( SELECT COALESCE(MAX(d_inner.position), 0) + 1 FROM UsedDiscounts ud JOIN Discounts d_inner ON ud.discount_id = d_inner.discount_id WHERE ud.user_id = '目标用户ID' AND d_inner.business_id = '目标商家ID' );
逻辑说明
- 子查询的第一部分:统计用户在每个商家已用折扣的最高Position,加1得到当前可使用的Position。
UNION ALL部分:专门处理用户从未使用过某商家折扣的场景,直接把资格Position设为1(第一个折扣)。- 最后通过关联筛选,精准定位到用户当前能使用的折扣。
内容的提问来源于stack exchange,提问作者Muhammad Umer
相关产品推荐
相关产品推荐

