MySQL如何从关联表中筛选当前活跃的服务订阅?
解决当前活跃订阅的筛选问题
你的核心问题是:只要订阅存在任何一条「当前处于暂停状态」的记录,就应该被排除,而原SQL会因为存在历史暂停或未来预约暂停的记录,错误地把这类订阅判定为活跃。
先明确「当前暂停」的判定规则:
- 暂停开始时间≤当前日期,且暂停结束时间≥当前日期 或 暂停结束时间为NULL(无限期暂停)
方案一:用NOT EXISTS直接排除当前暂停的订阅
这个方案逻辑最直观,直接筛选出「不存在当前暂停记录」的订阅:
SELECT s.* FROM service s WHERE NOT EXISTS ( SELECT 1 FROM suspensions sus WHERE sus.service_id = s.id AND sus.suspension_from <= CURDATE() AND (sus.suspension_to >= CURDATE() OR sus.suspension_to IS NULL) );
方案二:用LEFT JOIN筛选无当前暂停的订阅
如果习惯用JOIN的写法,可以关联当前暂停的记录,然后筛选没有匹配到的订阅:
SELECT s.* FROM service s LEFT JOIN suspensions sus ON s.id = sus.service_id AND sus.suspension_from <= CURDATE() AND (sus.suspension_to >= CURDATE() OR sus.suspension_to IS NULL) WHERE sus.id IS NULL;
原SQL的问题分析
你原来的SQL逻辑错误在于:当一个订阅同时有历史暂停和当前暂停记录时,LEFT JOIN会返回多条记录,其中历史暂停的记录会满足WHERE条件,导致整个订阅被错误保留。而正确的逻辑应该是只要存在任意一条当前暂停记录,就直接排除该订阅,不管它有没有其他状态的暂停记录。
另外注意你原SQL里的拼写错误:suspenstion_from应该是suspension_from,这个也会导致逻辑失效。
内容的提问来源于stack exchange,提问作者Piotr Kaczmarzyk
相关产品推荐
相关产品推荐

