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

如何查询单条件存在但另一条件缺失的数据及SQL语句优化

问题解答

一、通用查询思路:存在某条件,但另一条件为空/无对应值

当你需要找满足A条件,但不存在B条件(或者B条件为空)的数据时,核心是先锁定满足A的主体,再排除那些同时符合B条件的情况,常用方法有这几种:

  • 子查询(NOT EXISTS):最直观的方式,先找到满足A的记录,再确保该主体(比如商品编号)没有符合B条件的记录
  • 分组筛选(GROUP BY + HAVING):对主体分组,统计满足A和B的数量,只保留有A但无B的组
  • 左连接(LEFT JOIN):将满足A的表和满足B的表左连接,筛选出B表中无匹配的记录

二、你的具体SQL问题解决

先说说你原来的SQL为什么不对:

SELECT [Country_IBS] , [Item_Number] , [Price_List] , [Sales_Price] , [Currency] 
FROM [DATA_IBS].[dbo].[fact_List_Prices_ALL_ALL_COUNTRIES] 
where Price_List in ('01') and Price_List not in ('ma')

这个语句的逻辑是同一行数据的Price_List既是'01'又不是'ma'——但同一行的Price_List只能是一个值,所以它其实等价于Price_List = '01',自然会把那些同时有'ma'价格列表的商品也包含进来,因为只要有一行是'01'就会被选出来,不管这个商品有没有'ma'的行。

下面给你几种正确的写法:

方法1:用NOT EXISTS子查询(推荐,性能较好)

逻辑是:先找到所有Price_List为'01'的商品记录,同时确保这个商品不存在Price_List为'ma'的记录:

SELECT [Country_IBS] , [Item_Number] , [Price_List] , [Sales_Price] , [Currency] 
FROM [DATA_IBS].[dbo].[fact_List_Prices_ALL_ALL_COUNTRIES] main
WHERE main.Price_List = '01'
AND NOT EXISTS (
    SELECT 1
    FROM [DATA_IBS].[dbo].[fact_List_Prices_ALL_ALL_COUNTRIES] sub
    WHERE sub.Item_Number = main.Item_Number
    AND sub.Price_List = 'ma'
)

方法2:用GROUP BY + HAVING筛选

如果只需要商品编号和对应的'01'价格信息,可以先分组,确保每个商品只有'01'的价格列表,没有'ma':

SELECT [Country_IBS] , [Item_Number] , [Price_List] , [Sales_Price] , [Currency] 
FROM [DATA_IBS].[dbo].[fact_List_Prices_ALL_ALL_COUNTRIES]
WHERE Item_Number IN (
    SELECT Item_Number
    FROM [DATA_IBS].[dbo].[fact_List_Prices_ALL_ALL_COUNTRIES]
    WHERE Price_List IN ('01', 'ma')
    GROUP BY Item_Number
    HAVING COUNT(DISTINCT Price_List) = 1 
       AND MAX(Price_List) = '01' -- 确保唯一的那个是'01'
)
AND Price_List = '01'

方法3:左连接筛选无匹配的记录

把满足'01'的表和满足'ma'的表左连接,然后筛选出'ma'表中没有匹配的行:

SELECT main.[Country_IBS] , main.[Item_Number] , main.[Price_List] , main.[Sales_Price] , main.[Currency] 
FROM [DATA_IBS].[dbo].[fact_List_Prices_ALL_ALL_COUNTRIES] main
LEFT JOIN [DATA_IBS].[dbo].[fact_List_Prices_ALL_ALL_COUNTRIES] sub
    ON main.Item_Number = sub.Item_Number
    AND sub.Price_List = 'ma'
WHERE main.Price_List = '01'
AND sub.Item_Number IS NULL -- 表示没有对应的'ma'记录

这几种方法都能帮你筛选出只有'01'价格列表、没有'ma'价格列表的商品记录,你可以根据自己数据库的性能情况选择合适的写法~


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 18:07:31