编写SQL导出上周完成注册无操作客户列表及现有查询异常排查
错误原因
- 逻辑错误:你使用的
UNION是合并两个查询的结果集,而非校验用户是否存在操作记录,完全不符合需求逻辑。你当前的查询等价于「返回所有未完成注册且注册时间在2021-05-03至2021-05-29的用户 + 所有有发票记录的用户」,和你要的「完成注册且无操作的用户」完全相反。 - 条件写反:需求要求筛选完成注册的用户,你写的
completed_registration=False筛选的是未完成注册的用户。 - 时间范围错误:需求要求的时间范围是5月3日-9日,你写的结束时间是5月29日。
- 空表不影响前半段查询结果:因为
invoice_invoice是空表,UNION后的结果完全等于前半段SELECT的结果,所以会返回1个用户,就是你前半段查出来的未完成注册的用户。
正确SQL编写思路
首先明确需求规则:
- 筛选条件:用户已完成注册(
completed_registration=True) - 排除规则:用户在对应年份5月3日0点到5月9日24点期间,没有发票、支出、提款任意一类操作记录
Invoice、Expense都继承自Operation模型,默认会携带操作时间字段(通常为created_at/operation_time,可对应你的表结构调整),且关联对应用户ID字段。
参考SQL(以NOT EXISTS写法为例,性能更稳定)
SELECT id, phone, full_name, email FROM users_user u WHERE -- 筛选已完成注册的用户 u.completed_registration = True -- 若需要限定注册时间在目标周内可保留下一行,不需要可直接删除 AND u.date_joined BETWEEN '202X-05-03 00:00:00' AND '202X-05-09 23:59:59' -- 排除同期有发票记录的用户 AND NOT EXISTS ( SELECT 1 FROM invoice_invoice i WHERE i.user_id = u.id AND i.created_at BETWEEN '202X-05-03 00:00:00' AND '202X-05-09 23:59:59' ) -- 排除同期有支出记录的用户 AND NOT EXISTS ( SELECT 1 FROM expense_expense e WHERE e.user_id = u.id AND e.created_at BETWEEN '202X-05-03 00:00:00' AND '202X-05-09 23:59:59' ) -- 排除同期有提款记录的用户,需替换withdrawal_table为你实际的提款表名 AND NOT EXISTS ( SELECT 1 FROM withdrawal_table w WHERE w.user_id = u.id AND w.created_at BETWEEN '202X-05-03 00:00:00' AND '202X-05-09 23:59:59' );
注:请将SQL中的
202X替换为实际年份,user_id、created_at等字段名替换为你表中实际对应的字段名即可使用。
内容的提问来源于stack exchange,提问作者Dziugito Bizox
相关产品推荐
相关产品推荐

