想象一下这个例子,但是有更多的组件桶和更多的中间产品和输出。许多中间产物是在细节级别计算的,但有一些东西是在聚合级别计算的:
DECLARE @Profitability AS TABLE
(
Cust INT NOT NULL
,Category VARCHAR(10) NOT NULL
,Income DECIMAL(10, 2) NOT NULL
,Expense DECIMAL(10, 2) NOT NULL
,Liability DECIMAL(10, 2) NOT NULL
,AllocatedCapital DECIMAL(10, 2) NOT NULL
) ;
INSERT INTO @Profitability
VALUES ( 1, 'Software', 100, 50, 0, 0 ) ;
INSERT INTO @Profitability
VALUES ( 2, 'Software', 100, 20, 0, 0 ) ;
INSERT INTO @Profitability
VALUES ( 3, 'Software', 100, 60, 0, 0 ) ;
INSERT INTO @Profitability
VALUES ( 4, 'Software', 500, 400, 0, 0 ) ;
INSERT INTO @Profitability
VALUES (
5
,'Hardware'
,1000
,550
,0
,0
) ;
INSERT INTO @Profitability
VALUES (
6
,'Hardware'
,1000
,250
,500
,200
) ;
INSERT INTO @Profitability
VALUES (
7
,'Hardware'
,1000
,700
,500
,600
) ;
INSERT INTO @Profitability
VALUES (
8
,'Hardware'
,5000
,4500
,2500
,800
) ;
WITH ProfitView
AS ( SELECT Cust
,Category
,Income
,Expense
,Profit = Income - Expense
,NetProfit = Income - Expense
- CASE WHEN Liability - AllocatedCapital > 0
THEN Liability - AllocatedCapital
ELSE 0
END
FROM @Profitability
)
SELECT Cust
,Category
,Income
,Expense
,Profit
,NetProfit
,Margin = Profit / Income
,NetMargin = NetProfit / Income
FROM ProfitView ; -- NOTE I've left off the AFTER grouping formulas on this one.
WITH ProfitView
AS ( SELECT Cust
,Category
,Income
,Expense
,Profit = Income - Expense
,NetProfit = Income - Expense
- CASE WHEN Liability - AllocatedCapital > 0
THEN Liability - AllocatedCapital
ELSE 0
END
FROM @Profitability
),
GROUP1
AS ( SELECT Category
,SUM(Profit) AS Profit
,SUM(NetProfit) AS NetProfit
,SUM(Income) AS Income
,SUM(Profit) / SUM(Income) AS Margin
,SUM(NetProfit) / SUM(Income) AS NetMargin
FROM ProfitView
GROUP BY Category
),
GROUP2
AS ( SELECT GROUP1.*
,NetProfit - Profit AS Exposure
FROM GROUP1
)
SELECT *
,Exposure / Income AS ExposureRatio
FROM GROUP2 ;
WITH ProfitView
AS ( SELECT Cust
,Category
,Income
,Expense
,Profit = Income - Expense
,NetProfit = Income - Expense
- CASE WHEN Liability - AllocatedCapital > 0
THEN Liability - AllocatedCapital
ELSE 0
END
FROM @Profitability
),
GROUP1
AS ( SELECT SUM(Profit) AS Profit
,SUM(NetProfit) AS NetProfit
,SUM(Income) AS Income
,SUM(Profit) / SUM(Income) AS Margin
,SUM(NetProfit) / SUM(Income) AS NetMargin
FROM ProfitView
),
GROUP2
AS ( SELECT GROUP1.*
,NetProfit - Profit AS Exposure
FROM GROUP1
)
SELECT *
,Exposure / Income AS ExposureRatio
FROM GROUP2 ;
请注意,相同的公式必须在不同的聚合级别上使用。这会导致代码重复。
我曾考虑过使用UDF(标量或表值与外部应用程序,因为许多最终结果可能共享中间值,这些中间值必须在聚合级别计算),但根据我的经验,标量和多语句表值UDF的性能非常差。
基本上还考虑使用更动态的SQL和按名称应用公式。
是否有其他技巧、技术或策略来保持这些公式的同步和/或有组织地在不同的层次上应用?