Sql 中的子查询不起作用

Sql 中的子查询不起作用,sql,sql-server,Sql,Sql Server,我正在使用Transact-SQL Microsoft SQL Server 2014,以下是我的问题: 我正在使用标准的Northwind数据库进行实践,我想查看没有任何产品的类别列表 首先,我创建了一个新类别,其中没有任何产品: insert into Categories (CategoryName) values ('TestCategory') 然后我写了这个: SELECT CategoryName FROM Categories WHERE CategoryID N

我正在使用Transact-SQL Microsoft SQL Server 2014,以下是我的问题: 我正在使用标准的Northwind数据库进行实践,我想查看没有任何产品的类别列表

首先,我创建了一个新类别,其中没有任何产品:

insert into Categories (CategoryName) values ('TestCategory')
然后我写了这个:

  SELECT CategoryName 
  FROM Categories
  WHERE CategoryID NOT IN (select CategoryID from Products)
不幸的是,它什么也没给

我是这样理解的: 我想找到没有与之相关的产品的类别,所以我使用了 其中CategoryID不在“从产品中选择CategoryID”中,因为我想将“类别”表中的每个CategoryID与从“从产品中选择CategoryID”中获得的列表进行比较-此列表包括具有产品的每个类别。所以我认为使用NOT IN应该可以让我看到没有任何产品的类别


我希望你能理解我想要描述的。如果您能提供帮助,那就太好了。

Sql使用基于三个值的逻辑。您的表在“类别ID”列中必须包含null,这就是它不显示任何内容的原因,请将子查询修改为

 SELECT CategoryName 
  FROM Categories
  WHERE CategoryID NOT IN (select CategoryID from Products where catogoryID is not null)

Sql使用基于三个值的逻辑。表的“类别ID”列中必须包含null。这就是为什么它不显示任何内容,请将子查询修改为

 SELECT CategoryName 
  FROM Categories
  WHERE CategoryID NOT IN (select CategoryID from Products where catogoryID is not null)
“不在”不是一个好的构造。如果子查询返回的任何值为NULL,则它从不返回任何行。解决此问题的简单方法是在以下位置使用:

更好的修复方法是使用“不存在”:

这将以更直观的方式表现

请注意,此行为是ANSI标准行为。如果存在空值,则引擎不知道c.categoryId是否在列表中。因此,它返回NULL,该值被视为false。

NOT IN不是一个好的构造。如果子查询返回的任何值为NULL,则它从不返回任何行。解决此问题的简单方法是在以下位置使用:

更好的修复方法是使用“不存在”:

这将以更直观的方式表现


请注意,此行为是ANSI标准行为。如果存在空值,则引擎不知道c.categoryId是否在列表中。因此,它返回NULL,该值被视为false。

我还找到了另一个解决方案:

select CategoryName from Categories c LEFT OUTER JOIN Products p
ON c.CategoryID = p.CategoryID
where ProductName is null

我认为上面的答案更直观,但我只是想展示另一种处理方法。

我还找到了另一种解决方案:

select CategoryName from Categories c LEFT OUTER JOIN Products p
ON c.CategoryID = p.CategoryID
where ProductName is null

我认为上面的答案更直观,但我只是想展示另一种处理方法。

你能确认你的“TestCategory”确实存在吗?你的insert声明提交了吗?是的,肯定是的,下面的答案解决了这个问题。你能确认你的“TestCategory”确实存在吗?你的insert声明被提交了吗?是的,当然是,下面的答案解决了问题