自连接同表识别每日数据差异的SQL问题排查与写法咨询
问题分析与解决方案
1. 你的SQL语句为何返回空?
你写的左连接逻辑完全偏离需求:
SELECT * FROM table1 t1 LEFT JOIN table1 t2 ON (t1.id_number = t2.id_number) WHERE t1.id_number IS NULL
这个语句试图筛选t1中id_number为空的行,但你的目标是找当日存在、昨日不存在的新增记录,逻辑完全不匹配。左连接同表且关联自身ID,再过滤t1.id_number为空,除非表本身存在ID为空的行,否则必然返回空结果。
2. 正确筛选当日与前日差异的写法
假设表中有daily_date字段(DATE类型)存储数据所属日期,以下两种写法可精准找出当日新增的记录:
写法一:左连接筛选不存在的记录
SELECT t1.* FROM table1 t1 LEFT JOIN table1 t2 ON t1.id_number = t2.id_number AND t2.daily_date = CURDATE() - INTERVAL 1 DAY WHERE t1.daily_date = CURDATE() AND t2.id_number IS NULL;
逻辑:仅取今日的t1数据,左连接昨日的t2数据(按ID匹配),若t2中无对应ID,则说明该记录是今日新增。
写法二:用NOT EXISTS子查询
SELECT * FROM table1 t1 WHERE t1.daily_date = CURDATE() AND NOT EXISTS ( SELECT 1 FROM table1 t2 WHERE t2.id_number = t1.id_number AND t2.daily_date = CURDATE() - INTERVAL 1 DAY );
逻辑:直接筛选今日的记录,同时确保这些记录的ID在昨日数据中不存在,性能与左连接相近,具体执行效率取决于数据库优化器。
3. 日期筛选的常见误区
你写的WHERE daily_date is CURDATE() and daily_date is CURDATE()-1存在两处错误:
- 单个字段不可能同时等于两个不同日期,此条件永远返回空
- 日期计算需用标准语法
CURDATE() - INTERVAL 1 DAY表示前一天,避免直接用CURDATE()-1(部分数据库兼容但语法不标准) - 若
daily_date是DATETIME类型,需改为DATE(t1.daily_date) = CURDATE()来匹配日期部分
内容的提问来源于stack exchange,提问作者stackoverflowme
相关产品推荐
相关产品推荐

