0

我有一个用 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)))

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

4

3 回答 3

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)
于 2013-02-19T17:40:09.383 回答
1

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

顺便说一句,让我们回答你没有问的更好的问题,假设它@temp是从中加载的,Clients这样你就可以找到有问题的记录。你可以这样做:

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

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

于 2013-02-19T17:30:55.350 回答
1

我不太确定这里的确切问题是什么。但是,两者看起来都不错——从可读性的角度来看,我更喜欢第二个,但那是偏好。

性能方面,我认为您不会注意到差异。

于 2013-02-19T17:31:16.890 回答