这看起来应该是一个相对简单的查询,但有人可以解释为什么第二个查询不返回第2行和第3行但第三个查询没有?基本上,我如何使查询满足'not in'子句?
declare @t table (id int identity, code1 char(2), code2 char(2))
insert into @t (code1, code2) values ('AA','BB')
insert into @t (code1, code2) values ('AA','CC')
insert into @t (code1, code2) values ('DD','EE')
select * from @t where code1 = 'AA' and code2 = 'BB'
select * from @t where (code1 != 'AA' and code2 != 'BB')
select * from @t t1 left join @t t2 on t2.id = t1.id and t2.code1 = 'AA' and t2.code2 = 'BB' where t2.id is null
*已更新 *
感谢您的回答。我希望“(code1!='AA'和code2!='BB')”都需要评估,即第1行(AA,BB)将被滤除,但rwo 2(AA,CC)将被退回。
有没有简单的方法来规定需要满足两个约束,这是我希望通过使用括号和和语句来实现的?
答案 0 :(得分:2)
对于查询2,第二行code1 != 'AA'
为FALSE。
答案 1 :(得分:1)
实际上查询2应该只返回第3行,因为'DD'!='AA'和'EE'!='BB'
答案 2 :(得分:1)
使第二个查询等同于您需要的第三个查询:
select * from @t where (code1 != 'AA' or code2 != 'BB')
绘制一个逻辑表来计算出来:
Row p1 (code1 != 'AA') p2 (code2 != 'BB') p1 AND p2 p1 OR p2
--- ------------------ ------------------ --------- --------
1 false false false false
2 false true false true
3 true true true true
编辑:响应您的更新:将两个NOTS放在一起可以反直觉(再次,如果您需要了解它是如何工作的,请自己绘制一个逻辑表)。更明确的使用NOT的方法是将'NOT'移动到括号外Joe suggested:
select * from @t where NOT (code1 = 'AA' or code2 = 'BB')
答案 3 :(得分:0)
第二个查询无法返回记录2,因为它显示“code1!= AA” - 对于第二条记录不是这样,所以它应该只返回记录3.
答案 4 :(得分:0)
第三个查询是左连接 - 并且t1基本上没有条件因此t1的所有行都将被返回,即使t2上存在某些条件(t2中的行将被放入的条件过滤掉,但是它是一个左连接,它不会影响由t1返回的行
答案 5 :(得分:0)
作为一般原则:LEFT JOINED表中的字段不应出现在WHERE子句中。
SELECT * FROM CUSTOMER
LEFT OUTER JOIN
ORDERS
ON CUSTOMER.CustomerID = ORDERS.CustomerID
WHERE ORDERS.CustomerID <> 1208
WHERE子句将其转换为INNER JOIN。 如果要排除1208,请检查ORDERS.CustomerID。