我正在做一个作业,我需要比较两个表之间的三个收入字段,当它们中的任何一个不同时,我需要将值从表1更新为表2。
我的更新查询如下。
UPDATE OP
SET OP.CompCanceledRevenue = OPW.Comp_Canceled_Revenue__c,
OP.PriorYearOperatingRevenueAmt = OPW.PriorYearRevenueAmount,
OP.YTDOperatingRevenueAmt = OPW.YTDRevenueAmount,
FROM dbo.Product OP
INNER JOIN dbo.Product_Working OPW ON OPW.ProductCode = OP.ProductCode
AND (OP.CompCanceledRevenue <> OPW.Comp_Canceled_Revenue__c
OR OP.PriorYearOperatingRevenueAmt <> OPW.PriorYearRevenueAmount
OR OP.YTDOperatingRevenueAmt <> OPW.YTDRevenueAmount)
当我在SQL Server中运行此查询时,我看到它没有提取Product
表中“收入值”为NULL的某些需要更新的记录。
Product_Working
表具有值,但是当我将double值与NULL比较时,<>条件似乎不起作用。所以我如下更改了查询。
UPDATE OP
SET OP.CompCanceledRevenue = OPW.Comp_Canceled_Revenue__c,
OP.PriorYearOperatingRevenueAmt = OPW.PriorYearRevenueAmount,
OP.YTDOperatingRevenueAmt = OPW.YTDRevenueAmount,
FROM dbo.Product OP
INNER JOIN dbo.Product_Working OPW ON OPW.ProductCode = OP.ProductCode
AND (ISNULL(OP.CompCanceledRevenue, 0) <> ISNULL(OPW.Comp_Canceled_Revenue__c, 0)
OR ISNULL(OP.PriorYearOperatingRevenueAmt, 0) <> ISNULL(OPW.PriorYearRevenueAmount, 0)
OR ISNULL(OP.YTDOperatingRevenueAmt, 0) <> ISNULL(OPW.YTDRevenueAmount, 0))
此查询返回的结果是我想要的,但是要花费超过1个小时才能完成。 Product
表具有500,000行,而Product_Working
表具有约250,000行。第一个查询在不到一分钟的时间内返回了结果。
是否存在将double值与NULL比较的替代解决方案?还是有一种解决方案可以使第二个查询运行更快?
答案 0 :(得分:4)
似乎很明显,但其中每一个:
ISNULL(OP.CompCanceledRevenue,0) <> ISNULL(OPW.Comp_Canceled_Revenue__c,0)
可以重写为:
(
OP.CompCanceledRevenue <> OPW.Comp_Canceled_Revenue__c
OR (OP.CompCanceledRevenue IS NULL AND OPW.Comp_Canceled_Revenue__c IS NOT NULL)
OR (OP.CompCanceledRevenue IS NOT NULL AND OPW.Comp_Canceled_Revenue__c IS NULL)
)
直观上,您可能希望这样做会更慢,因为它包含的代码更多,但是实际上,ISNULL函数阻止查询使用这些列上的任何索引,而此较长的代码块将使用索引,因此可能会更快。
答案 1 :(得分:0)
选项1
使用dbo.Product OP和dbo.Product_Working OPW创建2个TEMP表。创建两个表时都使用nullull
例如
Select *
,isnull(PriorYearOperatingRevenueAmt) as PriorYearOperatingRevenueAmt_n
,isnull(YTDOperatingRevenueAmt) as YTDOperatingRevenueAmt_n
into ##tmpprod
from dbo.Product
对两个表执行相同操作,然后将它们连接起来。
选项2 将条件放在where子句
UPDATE OP
SET OP.CompCanceledRevenue = OPW.Comp_Canceled_Revenue__c,
OP.PriorYearOperatingRevenueAmt = OPW.PriorYearRevenueAmount,
OP.YTDOperatingRevenueAmt = OPW.YTDRevenueAmount,
FROM dbo.Product OP
INNER JOIN dbo.Product_Working OPW
ON OPW.ProductCode = OP.ProductCode
Where
( ISNULL(OP.CompCanceledRevenue,0) <> ISNULL(OPW.Comp_Canceled_Revenue__c,0)
OR ISNULL(OP.PriorYearOperatingRevenueAmt,0) <> ISNULL(OPW.PriorYearRevenueAmount,0)
OR ISNULL(OP.YTDOperatingRevenueAmt,0) <> ISNULL(OPW.YTDRevenueAmount,0))