Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL";选择不在子查询中的位置";不返回任何结果_Sql_Sql Server_Tsql - Fatal编程技术网

SQL";选择不在子查询中的位置";不返回任何结果

SQL";选择不在子查询中的位置";不返回任何结果,sql,sql-server,tsql,Sql,Sql Server,Tsql,免责声明:我已经解决了这个问题(我想),但我想把这个问题添加到堆栈溢出中,因为我(很容易)在任何地方都找不到它。另外,有人可能比我有更好的答案 我有一个数据库,其中一个表“Common”被其他几个表引用。我想看看公共表中哪些记录是孤立的(即,没有来自任何其他表的引用) 我运行了以下查询: select * from Common where common_id not in (select common_id from Table1) and common_id not in (select c

免责声明:我已经解决了这个问题(我想),但我想把这个问题添加到堆栈溢出中,因为我(很容易)在任何地方都找不到它。另外,有人可能比我有更好的答案

我有一个数据库,其中一个表“Common”被其他几个表引用。我想看看公共表中哪些记录是孤立的(即,没有来自任何其他表的引用)

我运行了以下查询:

select *
from Common
where common_id not in (select common_id from Table1)
and common_id not in (select common_id from Table2)
我知道有一些孤立的记录,但没有返回任何记录。为什么不呢


(这是SQL Server,如果有关系的话。)

表1或表2的公用id有一些空值。请改用此查询:

select *
from Common
where common_id not in (select common_id from Table1 where common_id is not null)
and common_id not in (select common_id from Table2 where common_id is not null)

就在我的头顶上

select c.commonID, t1.commonID, t2.commonID
from Common c
     left outer join Table1 t1 on t1.commonID = c.commonID
     left outer join Table2 t2 on t2.commonID = c.commonID
where t1.commonID is null 
     and t2.commonID is null
我做了一些测试,下面是我的结果w.r.t.@patmortech的答案和@rexem的评论

如果Table1或Table2未在commonID上编制索引,则会得到一个表扫描,但@patmortech的查询速度仍然是100K行主表的两倍

如果两者都没有在commonID上建立索引,则会得到两次表扫描,差异可以忽略不计


如果两者都在commonID上建立索引,“not exists”查询将以1/3的时间运行。

如果您希望世界是一个两值布尔位置,您必须自己防止null(第三个值)情况

SELECT T.common_id
  FROM Common T
       LEFT JOIN Table1 T1 ON T.common_id = T1.common_id
       LEFT JOIN Table2 T2 ON T.common_id = T2.common_id
 WHERE T1.common_id IS NULL
   AND T2.common_id IS NULL
不要写入允许列表端为空的子句。过滤掉它们

common_id not in
(
  select common_id from Table1
  where common_id is not null
)

让我们假设公共_id的这些值:

Common - 1
Table1 - 2
Table2 - 3, null
我们希望公共行返回,因为它不存在于任何其他表中。但是,null会抛出一个活动扳手

使用这些值,查询相当于:

select *
from Common
where 1 not in (2)
and 1 not in (3, null)
select *
from Common
where not (1=2)
and not (1=3 or 1=null)
这相当于:

select *
from Common
where 1 not in (2)
and 1 not in (3, null)
select *
from Common
where not (1=2)
and not (1=3 or 1=null)
问题就从这里开始。与空值比较时。因此,查询简化为

select *
from Common
where not (false)
and not (false or unkown)
false或unknown是未知的:

select *
from Common
where true
and not (unknown)
真实而非未知也是未知的:

select *
from Common
where unknown
where条件不会返回结果未知的记录,因此我们不会返回任何记录

处理这个问题的一种方法是使用exists操作符,而不是in。Exists从不返回UNKNOWN,因为它对行而不是列进行操作。(行存在或不存在;行级别没有任何空歧义!)


更新:

我博客中的这些文章更详细地描述了两种方法之间的差异:


有三种方法可以执行此查询:

  • 左连接/为空

    SELECT  *
    FROM    common
    LEFT JOIN
            table1 t1
    ON      t1.common_id = common.common_id
    WHERE   t1.common_id IS NULL
    
  • 不存在

    SELECT  *
    FROM    common
    WHERE   NOT EXISTS
            (
            SELECT  NULL
            FROM    table1 t1
            WHERE   t1.common_id = common.common_id
            )
    
  • 不在

    SELECT  *
    FROM    common
    WHERE   common_id NOT IN
            (
            SELECT  common_id
            FROM    table1 t1
            )
    
table1.common_id
不可为空时,所有这些查询在语义上都是相同的

当它可为空时,
不在
是不同的,因为
中(因此,
不在
中)当值与包含
的列表中的任何内容不匹配时,返回

这可能会让人困惑,但如果我们回忆起这方面的替代语法,可能会变得更加明显:

common_id = ANY
(
SELECT  common_id
FROM    table1 t1
)
此条件的结果是列表中所有比较的布尔乘积。当然,一个
NULL
值会产生
NULL
结果,它也会呈现整个结果
NULL

我们永远不能肯定地说,
common\u id
不等于此列表中的任何值,因为至少有一个值是
NULL

假设我们有这些数据:

common

--
1
3

table1

--
NULL
1
2
LEFT JOIN/IS NULL
NOT EXISTS
将返回
3
NOT IN
将不返回任何内容(因为它将始终计算为
FALSE
NULL

MySQL
中,如果在不可为NULL的列上,
LEFT JOIN/IS NULL
NOT In
NOT EXISTS
的效率要高一点(百分之几)。如果列可为空,
不存在
是最有效的(同样,也不是很多)

Oracle
中,所有三个查询都会生成相同的计划(一个
反连接

在SQL Server中,
不在
/
不存在
更有效,因为其优化器无法将
左连接/为空
优化为
反连接

PostgreSQL
中,
左连接/为空
不存在
不在
中更有效,因为它们被优化为
反连接
,而
不在
使用
散列子计划
(如果子查询太大而无法散列,则使用普通的
子计划
)这对我来说很有效:)

从“公用”中选择*

在哪里

公共id不在(从表1中选择ISNULL(公共id,'dummy-data')

和公共id不在(从表2中选择ISNULL(公共id,'dummy-data')


我举了一个例子,其中我正在查找,因为一个表中的值是双精度的,而另一个表中的值是字符串,所以它们不匹配(或者没有强制转换就不匹配)。但只有不在中。作为选择。。。在…中工作。奇怪,但我想我会与大家分享,以防其他人遇到这个简单的修复方法。

请按照下面的示例理解上述内容 主题:

您也可以访问以下链接了解

但是如果我们在中使用
NOT,那么我们就不会得到任何数据

select Department_name,department_id from hr.departments dep 
where department_id not in (select department_id from hr.employees );
没有找到任何数据

发生这种情况的原因是(
从hr.employees中选择部门id
)返回空值,并且整个查询的计算结果为false。我们可以看到,如果我们稍微像下面这样更改SQL,并使用NVL函数处理空值

select Department_name,department_id from hr.departments dep 
where department_id not in (select NVL(department_id,0) from hr.employees )
现在我们得到了数据:

DEPARTMENT_NAME DEPARTMENT_ID
Treasury    120
Corporate Tax   130
Control And Credit  140
Shareholder Services    150
Benefits    160
....

在使用NVL函数处理空值时,我们再次获得数据。

如果一个表中有数据,而另一个表中没有数据,该怎么办?你想要“and”或“or”吗?我在寻找任何表中都没有引用的记录,所以我想要and。我会澄清这个问题。那应该是where子句中的AND。否则,这个世界
select Department_name,department_id from hr.departments dep 
where department_id not in (select NVL(department_id,0) from hr.employees )
select Department_name,department_id from hr.departments dep 
where department_id not in (select NVL(department_id,0) from hr.employees )
DEPARTMENT_NAME DEPARTMENT_ID
Treasury    120
Corporate Tax   130
Control And Credit  140
Shareholder Services    150
Benefits    160
....