sql结合多个运算符

时间:2013-02-19 17:25:18

标签: sql sql-server-2008

我有一个我在MS-SQL中编写的查询,在插入之前必须检查有关客户端的信息是否已经在表中。如果一个实体已更改,则将插入该行。问题是我可以在where子句中组合运算符吗?现在我的查询看起来像这样:

select * from @Temp c
where exists (select * from Clients c2
            where (c.ClientId = c2.ClientId and c.ClientFName <> c2.FirstName) 
            or (c.ClientId = c2.ClientId and c.ClientLName <> c2.LastName)
            or (c.ClientId = c2.ClientId and c.ClientAddress <> c2.Address)
            or (c.ClientId = c2.ClientId and c.ClientCity <> c2.City)
            or (c.ClientId = c2.ClientId and c.ClientState <> c2.State)
            or (c.ClientId = c2.ClientId and c.ClientZip <> c2.Zip)

编写查询是否有任何优点或缺点:

select * from @Temp c
where exists (select * from Clients c2
            where (c.ClientId = c2.ClientId 
            and (c.ClientFName <> c2.FirstName 
            or c.ClientLName <> c2.LastName 
            or c.ClientAddress <> c2.Address 
            or c.ClientCity <> c2.City
            or c.ClientState <> c2.State
            or c.ClientZip <> c2.Zip)))

对我来说两个查询都有效,但写这个的最佳方式是什么?

3 个答案:

答案 0 :(得分:2)

实际上,如果查看两个查询的查询计划,您可能会发现优化程序将它们缩减为相同的内容。如果没有,那么您将选择提供最佳性能的版本(查询计划),但两者是等效的,优化器可能会注意到并利用它。

我注意到如果任何列允许空值,那么该列的比较是不合适的。你需要更像的东西:

OR c1.ClientAddress <> c2.ClientAddress
OR (c1.ClientAddress IS NULL AND c2.clientAddress IS NOT NULL)
OR (c1.ClientAddress IS NOT NULL AND c2.clientAddress IS NULL)

答案 1 :(得分:1)

任何时候你都可以消除冗余,这是一件好事。第二种方式获胜。 :)

顺便说一下,假设从@temp加载Clients以便您可以找到有问题的记录,让我们回答您没有提出的更好的问题。你可以做到:

SELECT * FROM Clients
WHERE clientid in (
    SELECT clientid from ( select distinct * from Clients ) t
    GROUP BY clientid HAVING count(*) > 1 )

(这也消除了null s)的比较混乱

答案 2 :(得分:1)

我不太确定这里的具体问题是什么。但是,两者看起来都很好 - 从可读性的角度来看,我更喜欢第二种,但这是偏好。

表现明智,我不认为你会注意到差异。