基于批次对比字段存在性:查询批次1独有code的最优SQL语句
最优SQL实现方案
针对你要找出存在于batch 1但不存在于batch 2的code值这个需求,我最推荐用NOT EXISTS的写法,这是大多数关系型数据库(MySQL、PostgreSQL、SQL Server等)下性能最优且最安全的方案:
SELECT DISTINCT t1.code FROM your_table t1 WHERE t1.batch = 1 AND NOT EXISTS ( SELECT 1 FROM your_table t2 WHERE t2.batch = 2 AND t2.code = t1.code );
为什么这是最优选择?
- 数据库优化器对
NOT EXISTS的处理非常高效:它会针对每条batch1的code,在batch2中查找匹配项,一旦找到就立即停止搜索,避免不必要的全表扫描。 - 如果给表加上联合索引
CREATE INDEX idx_batch_code ON your_table(batch, code);,这个查询的性能会直接拉满——索引可以让数据库快速定位到batch1和batch2的目标数据,不用遍历整张表。 - 加上
DISTINCT是为了避免batch1中存在重复的code值;如果你能确保batch1里的code都是唯一的,可以直接去掉这个关键字。
其他备选方案(供参考)
1. LEFT JOIN + IS NULL 写法
这个写法逻辑直观,适合新手理解:
SELECT DISTINCT t1.code FROM your_table t1 LEFT JOIN your_table t2 ON t1.code = t2.code AND t2.batch = 2 WHERE t1.batch = 1 AND t2.code IS NULL;
它的核心逻辑是把batch1的所有记录和batch2的code做左连接,最终t2.code IS NULL的部分就是batch1独有的code。在很多数据库中,它的性能和NOT EXISTS相差不大,但部分优化器对NOT EXISTS的优先级更高。
2. NOT IN(谨慎使用)
这个写法看起来简洁,但有致命的坑:
SELECT DISTINCT code FROM your_table WHERE batch = 1 AND code NOT IN ( SELECT code FROM your_table WHERE batch = 2 );
如果batch2的code字段中存在NULL值,整个查询会返回空结果!因为SQL中NULL和任何值的比较结果都是未知,NOT IN遇到这种情况会直接失效。除非你能100%保证batch2的code没有NULL,否则绝对不要用这个写法。
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

