SQL查询-如何同时使用存在和不存在条件

SQL查询-如何同时使用存在和不存在条件,sql,sql-server,Sql,Sql Server,我有两张桌子。TableA有一列newValue和oldValue。TableB有一个列值 我希望得到以下结果:从TableA中获取所有行,其中newValue存在于TableB中,oldValue不存在于TableB中 两个表都有许多行,因此性能非常重要 您将如何在SQL Server 2010/2012中实现这一点 u、 i:我找不到这个问题的产权 编辑: 我尝试的第一件事是: SELECT newValue, oldValue FROM TableA WHERE newValue IN (

我有两张桌子。TableA有一列newValue和oldValue。TableB有一个列值

我希望得到以下结果:从TableA中获取所有行,其中newValue存在于TableB中,oldValue不存在于TableB中

两个表都有许多行,因此性能非常重要

您将如何在SQL Server 2010/2012中实现这一点

u、 i:我找不到这个问题的产权

编辑:

我尝试的第一件事是:

SELECT newValue, oldValue
FROM TableA
WHERE newValue IN (SELECT value FROM TableB) 
  AND oldValue NOT IN (SELECT value FROM Table B)
但这是低效的,而且在我的数据库上的性能很差。我正在寻找其他解决方案。

请尝试:

Select Distinct A.*
From TableA A
     Inner Join TableB B on A.newValue = B.Value
Where A.OldValue NOT In (Select Value From TableB)
select * from TableA where newValue in (select value from TableB)
union
select * from TableA where oldValue not in (select value from TableB)
我认为回避是存在的,在这里有助于提高速度:

SELECT
        *
    FROM TableA
    WHERE
        (SELECT TOP 1 1 FROM TableB WHERE value = newValue) IS NOT NULL
        AND
        (SELECT TOP 1 1 FROM TableB WHERE value = oldValue) IS NULL

您可以使用exists/notexists

SELECT newValue, oldValue
FROM TableA as t1 
where exists(SELECT value FROM TableB as t2 where t1.newValue=t2.value) and 
 not exists(SELECT value FROM TableB as t3 where t1.olvalue=t3.value)
如果您有value、newvalue和oldvalue索引,可以尝试以下方法:

select
    a.newValue, a.oldValue
from TableA as a
where
    a.newValue in (select distinct b.value from TableB as b) and
    a.oldValue not in (select distinct b.value from TableB as b)
或存在:


您可以使用单个存在条件来执行此操作

 SELECT newValue, oldValue
 FROM TableA a
 WHERE exists 
 (
  SELECT 1 FROM TableB b 
  where a.newValue = b.value 
  and a.oldValue != b.value)

这还不够。我仍然需要从TableB中筛选那些TableA.oldValue不存在的行。这可能会返回重复的行。现在,如果存在文本列,则不同的A.*可能会失败。最好的解决方案是最接近您的解决方案。我用了一个连接+不存在在一起。其他的解决方案似乎更慢。所以我接受这个答案。谢谢没有SQL Server 2010,但这效率低下,而且在我的数据库上的性能很差,这并不意味着问题出在查询上,您可能会受益于基于值的索引,以及覆盖索引newValue INCLUDE oldValue或oldValue INCLUDE newValue。正如您所写,我在每个相关列上都有索引。您有三个或两个索引吗?我只建议两种方法。尝试所有查询和写入时间:SQL Server的查询计划器功能非常强大,完全有可能为相关子查询生成与非相关子查询等效的工厂。此方法可以返回重复行。a.newValue的不同部分是否在从表b中选择不同的b.value作为b以任何方式更改执行计划?我怀疑不是。当你做下一票时,有一个添加评论的习惯,这将帮助我们理解原因。我认为下一票支持你的答案。看,我也有下一票,即使它是公认的答案:。在子区中,它将始终从表b中选择1选择1。好像是打字错误。请更正!!即使你改变了,我也不确定这是否会带来预期的结果answer@huMptyduMpty. 我用的是这里的存在。只在in子句中检查值。Exist子句检查条件下是否存在值。所以在exists子句中,我们甚至可以执行existselect null from。投了否决票的用户没有留下评论。这就是为什么我添加了一条评论要求它。无论如何,谢谢您的关心。@Mani您的查询并不等同于OP的查询。您的查询将找到表A的所有行,其中newValue存在于表B中,并且oldValue与newValue不同,而OP的查询将检查新旧值与所有可能的B值,可能有人因此而对您投了反对票。
 SELECT newValue, oldValue
 FROM TableA a
 WHERE exists 
 (
  SELECT 1 FROM TableB b 
  where a.newValue = b.value 
  and a.oldValue != b.value)