1

SQLビューで、以前の計算が複雑になったり判読できなくなったりしないように、以前の計算を再利用する問題を処理するための最良の方法は何ですか。

ストアドプロシージャでは、@変数を格納/出力し、それらを使用して計算を実行できますが、私の問題は、これをビューで実行する必要があることです。

これについて行くための最良の方法は何ですか?(数千行のデータがあることを念頭に置いてください)。

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
4

1 に答える 1

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
于 2012-10-24T20:12:35.537 に答える