2016-04-14 58 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,然後您只需在最終選擇查詢中將計算字段選擇或過濾爲普通列,而無需進一步計算。

相關問題