In a SQL view, what is the best way to handle the problem of reusing previous calculations such that they do not become complex/unreadable.
In a stored proc, we could store/output @variables and do the calcs using them as we went along, but my problem is that this must be done in a view.
What’s the best way to go about this? (bearing in mind there are a few thousand rows of data).
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
Personally, I’d just subquery them. Although to be honest, SQL Server sees through the “wraps” and does reuse the expressions; you can verify that by checking the execution plan.