排除在另一行中找不到列的值的行

时间:2014-07-16 23:37:05

标签: sql sql-server

这是前一个问题的后续问题,但与Find rows where value in column not found in another row

相反

给定一个表Table1,列Key1 (int), Key2 (int), and Type (varchar) ...

我想排除任何两行      Type等于'TypeA'Key2等于Null  在表中有相应的行      Type等于'TypeB'Key2等于来自另一行的Key1

所以,给定数据

**KEY1**     **Key2**     **Type**
   1           NULL         TypeA
   2           5            TypeA
   3           1            TypeB
   4           NULL         TypeA
   5           NULL         TypeB
   6           26           TypeC
   7           NULL         TypeD
   8           NULL         TypeD

我想返回除Key = 1和Key = 3之外的所有行,因为这些行一起符合Type =' TypeA' / Key2 = NULL的条件,并且确实有一个对应的Type类型='的TypeB' /键1 =密钥2

2 个答案:

答案 0 :(得分:1)

试试这个:http://sqlfiddle.com/#!6/fffcb/2

select a.*
from demo a
left outer join demo b
on 
(
  b.key2 = a.key1
  and a.[Type] = 'TypeA'
  and b.[Type] = 'TypeB'
  and a.Key2 is null
)
or
(
  b.key1 = a.key2
  and b.[Type] = 'TypeA'
  and a.[Type] = 'TypeB'
  and b.Key2 is null
)
where b.key1 is null 

答案 1 :(得分:1)

这是一个使用not exists的解决方案,它应该比左外连接更快(参见:http://sqlinthewild.co.za/index.php/2010/03/23/left-outer-join-vs-not-exists/)。

SELECT *
FROM demo d1
WHERE NOT ((TYPE LIKE 'TypeA'
            AND Key2 IS NULL
            AND EXISTS
              (SELECT 1
               FROM demo d2
               WHERE d2.TYPE='TypeB'
                 AND d2.Key2 = d1.key1))
           OR (TYPE LIKE 'TypeB'
               AND Key2 IS NOT NULL
               AND EXISTS
                 (SELECT 1
                  FROM demo d2
                  WHERE d2.TYPE='TypeA'
                    AND d2.Key1 = d1.key2)));

你应该在key1和key2上有索引。

CREATE INDEX index_key1
ON demo (key1);

CREATE INDEX index_key2
ON demo (key2);