2016-04-14 63 views
3

我写了下面的查询,其中工作正常&产生正确的结果。不过,我认为这可能不是非常有效,因为我的SQL经验非常有限。用查询计算最有效的方法

突出的主要是我在哪里计算价格差异的名义差异,这两条线。

1. isnull(hld.Nominal, 0) - isnull(nav.Nominal, 0) NomDiff 
2. isnull((hld.Price/nav.LocalPrice - 1) * 100, 0) 

因为我也必须把这两行放在where条件中,所以同样的计算被计算两次。什么是写这个查询的更好方法?

;WITH hld AS 
(
    SELECT id, 
      name, 
      Nominal, 
      Price 
    FROM tblIH 
), 
nav AS 
(
    SELECT id, 
      name, 
      Nominal, 
      LocalPrice 
    FROM tblNC 
) 
SELECT COALESCE(hld.id, nav.id) id, 
     COALESCE(nav.name, hld.name) name, 
     ISNULL(hld.Nominal, 0) HldNom, 
     ISNULL(nav.Nominal, 0) NavNom, 
     ISNULL(hld.Nominal, 0) - ISNULL(nav.Nominal, 0) NomDiff, 
     ISNULL(hld.Price, 0) HldPrice, 
     ISNULL(nav.LocalPrice, 0) NavPrice, 
     ISNULL((hld.Price/nav.LocalPrice - 1) * 100, 0) 
FROM hld 
FULL OUTER JOIN nav ON hld.id = nav.id 
WHERE ISNULL(hld.Nominal, 0) - ISNULL(nav.Nominal, 0) <> 0 
    OR ISNULL((hld.Price/nav.LocalPrice - 1) * 100, 0) <> 0 
+2

我建议您包括样本数据,期望的结果以及您正在尝试做什么的解释。 –

+0

你使用了COALESCE而不是ISNULL,但你的可能会有相同的性能。 COALESCE有时会稍微好一点,因为你多次呼叫INSULL可以获得一些性能 – Antonio

+1

您可以在第二个CTE中包含计算部分,那么您可以简单地选择或过滤计算的字段作为最终选择中的列名查询无需进一步计算。 –

回答

1

首先选择没有where条件,就得结果作为表TMP,然后添加其中条件用柱NomDiff和PriceDiff

;WITH hld AS 
(
    SELECT id, 
      name, 
      Nominal, 
      Price 
    FROM tblIH 
), 
nav AS 
(
    SELECT id, 
      name, 
      Nominal, 
      LocalPrice 
    FROM tblNC 
) 
select * 
from (SELECT COALESCE(hld.id, nav.id) id, 
      COALESCE(nav.name, hld.name) name, 
      ISNULL(hld.Nominal, 0) HldNom, 
      ISNULL(nav.Nominal, 0) NavNom, 
      ISNULL(hld.Nominal, 0) - ISNULL(nav.Nominal, 0) NomDiff, 
      ISNULL(hld.Price, 0) HldPrice, 
      ISNULL(nav.LocalPrice, 0) NavPrice, 
      ISNULL((hld.Price/nav.LocalPrice - 1) * 100, 0) PriceDiff 
    FROM hld 
    FULL OUTER JOIN nav ON hld.id = nav.id) tmp 
where NomDiff <> 0 or PriceDiff <> 0 
1

计算部分可以包括在所述第二CTE,然后您只需在最终选择查询中将计算字段选择或过滤为普通列,而无需进一步计算。

相关问题