You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将含NOT IN的子查询转换为JOIN或WITH语句?附SQL示例

替换NOT IN子查询为JOIN或WITH写法的解决方案

嘿,我来帮你把这两个SQL语句里的NOT IN子查询转换成更高效、更易维护的写法~

1. 查询语句(SELECT)的优化

原语句:

SELECT * FROM ViewBuy99 WHERE Id NOT IN ( SELECT Id FROM Buy99 );

推荐用LEFT JOIN写法(性能更优)

SELECT v.* 
FROM ViewBuy99 v
LEFT JOIN Buy99 b ON v.Id = b.Id
WHERE b.Id IS NULL;

这个逻辑是用LEFT JOIN保留ViewBuy99的所有记录,然后匹配Buy99中相同的Id,那些没有匹配到的记录(也就是b.Id为NULL的行),就是不在Buy99里的数据,和原NOT IN功能完全一致。而且相比子查询,JOIN的执行计划通常更高效,尤其是在数据量较大的场景下。另外,如果Buy99的Id存在NULL值,NOT IN会因为NULL的比较逻辑返回不符合预期的结果,而LEFT JOIN写法可以避免这个坑。

用WITH子句优化结构(适合复杂场景)

如果只是为了让查询结构更清晰(比如后续要复用Buy99的Id集合),可以用WITH子句:

WITH Buy99Ids AS (
    SELECT Id FROM Buy99
)
SELECT * FROM ViewBuy99 WHERE Id NOT IN (SELECT Id FROM Buy99Ids);

这个写法逻辑和原语句一致,但把子查询提取成了可复用的公共表达式,在复杂查询中可读性更好。

2. 插入语句(INSERT)的优化

原语句:

INSERT INTO Buy99 SELECT * FROM ViewBuy99 WHERE Id NOT IN ( SELECT Id FROM Buy99 );

同样用LEFT JOIN替换:

INSERT INTO Buy99
SELECT v.* 
FROM ViewBuy99 v
LEFT JOIN Buy99 b ON v.Id = b.Id
WHERE b.Id IS NULL;

这个写法和原插入语句的功能完全相同,而且避免了嵌套子查询,执行效率更高,同时也解决了NOT IN遇到NULL的潜在问题。

内容的提问来源于stack exchange,提问作者soodi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:14:31