带NOT的SQL查询不返回任何行

带NOT的SQL查询不返回任何行,sql,plsql,Sql,Plsql,我有一个sql语句 select t.name, t.company from company t inner join employee e on t.id = e.emp_id where t.name not in(select t.name from table1 where t.id='x') 上述查询不返回任何行 但是,当我删除子查询时,只需使用 select t.name, t.company from company t inner join employee e on

我有一个sql语句

select t.name, t.company from company t inner join employee e
on t.id = e.emp_id
where t.name not in(select t.name from table1 where t.id='x')
上述查询不返回任何行

但是,当我删除子查询时,只需使用

select t.name, t.company from company t inner join employee e
    on t.id = e.emp_id  
我得到所需的行

此外,子查询

select t.name from table1 where t.id='x'
在自身执行时提供数据行。我的语法是否不正确?

一个常见原因是子查询中的空值。但你有一个不同的问题。以下是您的疑问:

select t.name, t.company
from company t inner join employee e
     on t.id = e.emp_id
where t.name not in(select t.name from table1 where t.id='x')
子查询中的t.name是指外部查询中公司的t。也就是说,查询正在检查t.name中是否有t.name,而t.name始终为false。子查询需要表1中的名称。不使用别名可修复此问题:

select t.name, t.company
from company t inner join employee e
     on t.id = e.emp_id
where t.name not in(select name from table1 where id='x')
更好的是,使用有意义的别名,即表名的缩写:

select c.name, c.company
from company c inner join employee e
     on c.id = e.emp_id
where c.name not in (select t1.name from table1 t1 where t1.id = 'x')
一个常见的原因是子查询中的空值。但你有一个不同的问题。以下是您的疑问:

select t.name, t.company
from company t inner join employee e
     on t.id = e.emp_id
where t.name not in(select t.name from table1 where t.id='x')
子查询中的t.name是指外部查询中公司的t。也就是说,查询正在检查t.name中是否有t.name,而t.name始终为false。子查询需要表1中的名称。不使用别名可修复此问题:

select t.name, t.company
from company t inner join employee e
     on t.id = e.emp_id
where t.name not in(select name from table1 where id='x')
更好的是,使用有意义的别名,即表名的缩写:

select c.name, c.company
from company c inner join employee e
     on c.id = e.emp_id
where c.name not in (select t1.name from table1 t1 where t1.id = 'x')

我假设表1中可能有空值。如果表1中的值为null,则需要在WHERE NOT in查询中显式排除null:

select t.name, t.company 
from company t 
inner join employee e
  on t.id = e.emp_id
where t.name not in(select name 
                    from table1 
                    where id='x'
                       and name is not null);

您还将看到我删除了t。来自WHERE子句查询的别名。您使用的别名与外部表公司关联。您需要更改别名或将其删除

我假设表1中可能有空值。如果表1中的值为null,则需要在WHERE NOT in查询中显式排除null:

select t.name, t.company 
from company t 
inner join employee e
  on t.id = e.emp_id
where t.name not in(select name 
                    from table1 
                    where id='x'
                       and name is not null);
您还将看到我删除了t。来自WHERE子句查询的别名。您使用的别名与外部表公司关联。您需要更改别名或将其删除

这是因为NOT IN NULL总是false

也一样

使用“不存在”替代:

跟进:

这是因为NOT IN NULL总是false

也一样

使用“不存在”替代:


跟进:

不确定为什么海报接受了错误的答案。是查询中有错误,应更改以下内容:

其中t.name未插入从表1中选择t.name

致:

其中t.name未插入从表1 t1中选择t1.name


然而,一旦这样做了,用户的困境仍然是一样的。使用notexists是一种解决方法,但可以避免真正的问题。真正的解决方案是发布者发布的解决方案,即在子查询中添加一个过滤器以排除空值。

不确定为什么发布者接受了错误的答案。是查询中有错误,应更改以下内容:

其中t.name未插入从表1中选择t.name

致:

其中t.name未插入从表1 t1中选择t1.name


然而,一旦这样做了,用户的困境仍然是一样的。使用notexists是一种解决方法,但可以避免真正的问题。真正的解决方案是由发布的,即在子查询中添加一个过滤器以排除空值。

t.name而不是int.name是这里的问题。这永远不会是真的。这是因为至少有一个t.name为null。您没有抓住要点。即使看不到空值,查询也不可能为真。三分之三是错的。你说得对,他也用t。别名,而不是使用其他表别名。你会注意到我也纠正了这一点。但是这个打字错误本身就足以导致所描述的问题,那么为什么要明确地断言它不是空的呢?这里的问题是t.name不是int.name。这永远不会是真的。这是因为至少有一个t.name为null。您没有抓住要点。即使看不到空值,查询也不可能为真。三分之三是错的。你说得对,他也用t。别名,而不是使用其他表别名。你会注意到我也纠正了这一点。但是这个打字错误本身就足以导致所描述的问题,那么为什么要明确地断言它不是空的呢?