2012-10-24 29 views
1

在SQL視圖中,處理重複使用先前計算的問題的最佳方式是,它們不會變得複雜/不可讀。在Transact SQL視圖中分解/重複使用複雜計算

在一個存儲過程中,我們可以存儲/輸出@variables並使用它們進行計算,但我的問題是這必須在視圖中完成。

這是什麼最好的方法呢? (記住有幾千行數據)。

SELECT 
     /* CALC 1 output to view row */ 
     (SELECT Act.ValueInContractCurrency/dbo.[Contract].Value * 
      (SELECT ISNULL(SUM(dbo.Invoice.ValueInContractCurrency),0) 
      FROM dbo.Invoice 
      WHERE dbo.Invoice.StageId = Act.StageId)) AS InvoicedValueInContractCurrency, 

     /* CALC 2 wraps CALC1 inside it and outputs to view row */ 
     (SELECT Act.ValueInContractCurrency - 
      (SELECT Act.ValueInContractCurrency/dbo.[Contract].Value * 
       (SELECT ISNULL(SUM(dbo.Invoice.ValueInContractCurrency),0) 
       FROM dbo.Invoice 
       WHERE dbo.Invoice.StageId = Act.StageId))) AS RemainingValueInContractCurrency,   

     /* CALC 3 wraps CALC2 inside it (which in turn wraps CALC1) and outputs to view row */ 
     (SELECT ConCurrency.CurrentExchangeRate/dbo.[Contract].CostedExchangeRate * 
      (SELECT Act.ValueInContractCurrency - 
       (SELECT Act.ValueInContractCurrency/dbo.[Contract].Value * 
        (SELECT ISNULL(SUM(dbo.Invoice.ValueInContractCurrency),0) 
        FROM dbo.Invoice 
        WHERE dbo.Invoice.StageId = Act.StageId)))) AS RemainingValueInFacilityCurrency 

     /* etc... for 10 more calcs that get increasingly long and unreadable via wrapping */ 

     FROM dbo.Activity AS Act 
     JOIN dbo.Stage ON Act.StageId = dbo.Stage.Id  
     JOIN dbo.[Contract] ON dbo.Stage.ContractId = dbo.[Contract].Id 
     JOIN dbo.Facility ON dbo.[Contract].FacilityId = Facility.Id 
     JOIN dbo.Currency AS FacCurrency ON dbo.Facility.CurrencyId = FacCurrency.Id 
     JOIN dbo.Currency AS ConCurrency ON dbo.[Contract].CurrencyId = ConCurrency.Id 

回答

2

就我個人而言,我只是子查詢他們。儘管說實話,SQL Server通過「包裝」來看待並重用表達式;你可以通過檢查執行計劃來驗證。

 /* etc... for 10 more calcs that get increasingly long and unreadable via wrapping */ 

SELECT *, 
     /* CALC 3 wraps CALC2 inside it (which in turn wraps CALC1) and outputs to view row */ 
     (SELECT CurrentExchangeRate/CostedExchangeRate * 
      RemainingValueInContractCurrency) AS RemainingValueInFacilityCurrency 
FROM (
SELECT *, 
     /* CALC 2 wraps CALC1 inside it and outputs to view row */ 
     (SELECT ValueInContractCurrency - 
      InvoicedValueInContractCurrency) AS RemainingValueInContractCurrency 
FROM (
SELECT *, 
     /* CALC 1 output to view row */ 
     (SELECT Act.ValueInContractCurrency/dbo.[Contract].Value * 
      (SELECT ISNULL(SUM(dbo.Invoice.ValueInContractCurrency),0) 
      FROM dbo.Invoice 
      WHERE dbo.Invoice.StageId = Act.StageId)) AS InvoicedValueInContractCurrency 
     FROM dbo.Activity AS Act 
     JOIN dbo.Stage ON Act.StageId = dbo.Stage.Id  
     JOIN dbo.[Contract] ON dbo.Stage.ContractId = dbo.[Contract].Id 
     JOIN dbo.Facility ON dbo.[Contract].FacilityId = Facility.Id 
     JOIN dbo.Currency AS FacCurrency ON dbo.Facility.CurrencyId = FacCurrency.Id 
     JOIN dbo.Currency AS ConCurrency ON dbo.[Contract].CurrencyId = ConCurrency.Id 
     ) A 
     ) B 
+0

試圖運行它迅速與您鍵入,並得到這個:消息8156,級別16,狀態1,行26 列「ID」被指定爲「A」多次。 消息4104,級別16,狀態1,行10 無法綁定多部分標識符「Act.ValueInContractCurrency」。 消息8156,級別16,狀態1,行26 「Id」列多次指定爲'B'。 Msg 4104,Level 16,State 1,Line 5 無法綁定多部分標識符「ConCurrency.CurrentExchangeRate」。 Msg 4104,Level 16,State 1,Line 5 無法綁定多部分標識符「dbo.Contract.CostedExchangeRate」。 – jimasp

+0

我的歉意。查詢已更新。在最內層,確保計算中需要的所有列都包含在內,並且如果存在重複的列名(表之間),則需要別名。在外部查詢中,直接使用列名而不使用表別名。 – RichardTheKiwi

+0

現在全部排序。標記爲答案。非常感謝。 – jimasp