我有一个查询,它应该返回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 ....
请帮助我弄清楚如何编写将检查多个列的查询?
谢谢!
答案 0 :(得分:5)
您也可以使用EXCEPT
:
SELECT DISTINCT fldID, fldValue FROM T1
EXCEPT
SELECT T1.fldID, T1.fldValue
FROM T2
JOIN T1 ON T2.fldID = T1.fldPtr
答案 1 :(得分: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()。
答案 2 :(得分: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
)
答案 3 :(得分: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
)
答案 4 :(得分:0)
如果两个表中的结构相同,则可以使用EXCEPT运算符http://technet.microsoft.com/en-us/library/ms188055.aspx
在更一般的情况下,您必须使用左连接并在第二个表中查找空元素。
答案 5 :(得分: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)
答案 6 :(得分:0)
这是更容易查询。它返回所有未链接到T2
中记录的T1.fldIDSELECT DISTINCT T1.fldID
FROM T1
LEFT JOIN T2 ON T2.fldID = T1.fldPtr
WHERE T2.fldID IS NULL
答案 7 :(得分:0)
使用IN排除大量值对于性能而言非常糟糕。请尝试以下方法:
SELECT T1.*
FROM T1
LEFT JOIN T2 ON T2.fldID = T1.fldPtr AND T1.fldValue = T2.fldvalue
WHERE T2.fldID IS NULL
答案 8 :(得分:0)
(从我的评论:)您不必在子查询中再次引用t1。这样做会导致select all the records from t1 that don't exist in t1 ...
形式的逻辑,它始终为空,就像select all blue balls that are not blue
或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
,使子查询不引用主查询中的任何表或别名:它返回True
(某些行存在)或False
,结果与主查询中的行完全不相关。 (使用别名而不是查询中的真实表名称的另一个好理由)