0

我有一个查询,它应该返回 T1 中未链接到 T2 中的记录的所有记录:

SELECT DISTINCT fldID, fldValue FROM T1 
 WHERE NOT EXISTS
 (
  SELECT  T1.fldID, T1.fldValue
    FROM T2
    JOIN T1  ON T2.fldID = T1.fldPtr
 )      

但它返回空集——应该是一条记录。

如果我使用这样的查询(一个字段上的子句):

SELECT DISTINCT fldID FROM T1 
 WHERE fldID NOT IN
 (
  SELECT  T1.fldID
    FROM T2
   JOIN T1  ON T2.fldID = T1.fldPtr
 )      

它返回正确的结果。

但是 SQL Server 不支持语法

WHERE ( fldID, flrValue ) NOT IN .... 

请帮我弄清楚如何编写将检查几列的查询?

谢谢!

4

9 回答 9

5

您也可以EXCEPT为此使用:

SELECT DISTINCT fldID, fldValue FROM T1 

EXCEPT

SELECT  T1.fldID, T1.fldValue
FROM T2
    JOIN T1  ON T2.fldID = T1.fldPtr
于 2013-10-10T08:18:52.620 回答
2

适用于每个数据库的更高效、更优雅的查询是:

SELECT T1.*
FROM T1
LEFT JOIN T2
    ON T2.fldID = T1.fldPtr
    AND T2.flrValue = T1.flrValue
WHERE T2.fldID IS NULL

LEFT JOIN 尝试使用这两个条件进行匹配,然后 WHERE 子句过滤连接,对于 LEFT JOINed 表,只有非连接具有 NULL 值。

恕我直言,这种方法几乎是查找不匹配项的行业标准。它通常比 NOT EXISTS() 更有效,尽管一些数据库无论如何都会优化 NOT EXISTS() 到这个查询。

于 2013-10-10T08:21:41.813 回答
1

如果子查询连接,请使用这两个列:

SELECT DISTINCT fldID, fldValue FROM T1 
WHERE NOT EXISTS
(
    SELECT * 
    FROM T2
    JOIN T1 ON T2.fldID = T1.fldPtr
           AND T1.fldValue = T2.flrValue 
)   
于 2013-10-10T08:18:04.360 回答
0

类似的东西(我想,因为我不确定我 100% 理解你的问题):

SELECT DISTINCT fldID FROM T1 
 WHERE fldID NOT IN
 (
  SELECT  T1.fldID
    FROM T2
   JOIN T1  ON T2.fldID = T1.fldPtr
  WHERE T2.flrValue = T1.flrValue
 )  
于 2013-10-10T08:18:09.227 回答
0

如果两个表中的结构相同,则可以使用 EXCEPT 运算符http://technet.microsoft.com/en-us/library/ms188055.aspx

在更一般的情况下,您必须使用左连接并在第二个表中查找空元素。

于 2013-10-10T08:19:16.513 回答
0

试试下面的查询。

select DISTINCT fldID
from Table1
WHERE cast(fldID as varchar(100))+'~'+cast(flrValue as varchar) 
NOT IN (select cast(fldID as varchar(100))+'~'+cast(flrValue as varchar) from table2)
于 2013-10-10T08:27:39.053 回答
0

这更容易查询。它返回所有未链接到 T2 中记录的 T1.fldID

SELECT DISTINCT T1.fldID
FROM T1
LEFT JOIN T2 ON T2.fldID = T1.fldPtr
WHERE T2.fldID IS NULL
于 2013-10-10T08:28:06.517 回答
0

使用 IN 排除大量值对性能来说是很糟糕的。尝试以下操作:

SELECT T1.*
FROM T1
    LEFT JOIN T2 ON T2.fldID = T1.fldPtr AND T1.fldValue = T2.fldvalue
WHERE T2.fldID IS NULL
于 2013-10-10T08:29:54.540 回答
0

(来自我的评论:)您不必在子查询中再次引用 t1 。这样做会导致表单的逻辑select all the records from t1 that don't exist in t1 ...始终为空,就像select all blue balls that are not blue, or select all odd numbers that are even... 第一个查询应该是:

SELECT DISTINCT fldID, fldValue
FROM T1 
WHERE NOT EXISTS (
  SELECT * FROM T2
   WHERE T2.fldID = T1.fldPtr
 );

并且:在您的原始查询中,子查询是不相关的:t1子查询中的 遮蔽t1查询TrueFalse的与主查询中的行完全不相关。(在查询中使用别名而不是真实表名的另一个很好的理由)

于 2013-10-10T11:47:01.730 回答