1

在 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
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 回答