JOIN与WHERE子句的SQL过滤差异及查询失效问题解析
关于SQL查询无结果的问题解析
在DataLemur的一道练习题中,我编写的初始SQL查询未返回任何结果,但更换写法后得到了正确结果,以下是两种写法的解析及问题原因说明:
初始查询代码(无结果)
SELECT * FROM emails e INNER JOIN texts t ON e.signup_date::date = (t.action_date + interval '1 day')::date AND e.email_id = t.email_id WHERE t.signup_action = 'Confirmed'
正确查询代码(返回结果)
SELECT DISTINCT user_id FROM emails e INNER JOIN texts t on e.email_id = t.email_id WHERE (t.action_date)::date - e.signup_date::date = 1 and signup_action = 'Confirmed'
两种写法的SQL解析逻辑及问题原因
初始写法的解析与错误
- SQL执行时,会先执行
INNER JOIN的ON条件:先匹配email_id相同的记录,再筛选出signup_date等于action_date加1天的记录对,最后才在WHERE中过滤signup_action='Confirmed'的记录。 - 核心错误是日期逻辑完全颠倒:题目要求的是用户在注册次日完成确认,也就是
action_date应该是signup_date + 1天,但初始写法写成了signup_date = action_date + 1天,相当于找“注册日期比确认日期晚一天”的记录,这和业务需求完全相反,自然没有符合条件的关联结果,最终返回空。
正确写法的解析
- 先通过
email_id关联两张表的所有匹配记录,然后在WHERE子句中判断确认日期与注册日期的差值为1天,精准匹配“注册次日确认”的场景,同时过滤出确认动作的记录,最后用DISTINCT去重得到唯一的用户ID,符合题目要求。
内容的提问来源于stack exchange,提问作者codeninja
相关产品推荐
相关产品推荐

