2010-08-11 70 views
1

我有两个T-SQL标量函数,它们都对大量数据进行计算(花费大量时间)并返回一个值,例如, CalculateAllIncomes(EmployeeID)和CalculateAllExpenditures(EmployeeID)。如何避免在需要组合结果时多次调用T-SQL函数?

我运行调用这些并返回结果为每个员工的SELECT语句。我还需要将每个员工的余额计算为AllIncomes-AllExpenditures。

我有一个函数为getBalance(雇员)调用所述两个上述功能并返回结果{CalculateAllIncomes(EmployeeID) - CalculateAllExpenditures(EmployeeID)}。但是,如果我这样做:

Select CalculateAllIncomes(EmployeeID), CalculateAllExpenditures(EmployeeID), GetBalance(EmployeeID) ....函数CalcualteAllIncomes()和CalculateAllExpenditures被调用两次(一次明确地,一次在GetBalance函数中),因此生成的查询需要两次。

我想找到一些更好的解决方案。我想:

select alculateAllIncomes(EmployeeID), AS Incomes, CalculateAllExpenditures 
(EmployeeID) AS Expenditures, (Incomes - Expenditures) AS Balance.... 

但它抛出错误:

无效的列名收入和

无效的列名的支出。

我敢肯定,必须有一个简单的解决方案,但我不能弄明白。出于某种原因,我似乎无法在SELECT子句中使用列别名。是这样吗?如果是这样,在这种情况下可以采取什么解决方法? 感谢您的任何建议。

+0

你可以在你的客户端代码中进行组合吗? – Paddy 2010-08-11 11:58:33

+0

此选择语句是在应用程序的不同位置多次使用的视图的一部分。所以我认为将它包含在视图中是有意义的,这样我就不必在不同的地方重写相同的计算。毕竟我认为这是Views的全部目的。 – Trex 2010-08-13 08:31:07

回答

5

忘记函数调用:你也许可以做到这一点,在一个标准的查询一切。

函数调用滥用(试图为OO封装)强迫你这种情况。另外,如果你在Employee表中有每行的GetBalance(EmployeeID),那么你就是在表的CURSORing。你现在也通过多次调用来实现这一点。

你需要的是这样的:

;WITH cSUMs AS 
(
SELECT 
    SUM(CASE WHEN type = 'Incomes' THEN SomeValue ELSE 0 END) AS Income), 
    SUM(CASE WHEN type = 'Expenditures' THEN SomeValue ELSE 0 END) AS Expenditure) 
FROM 
    MyTable 
WHERE 
    EmployeeID = @empID --optional for all employees 
GROUP BY 
    EmployeeID 
) 
SELECT 
    Income, Expenditure, Income - Expenditure 
FROM 
    cSUMs 

有一次,我从周末查询到下一个第二消除这种OO的基于汇总查询沼泽标准的定势思维。

+0

我会给你100万分的OO封装评论。当您尝试使用面向对象编程规则时,关系数据库不会表现得最好。 – HLGEM 2010-08-11 17:37:52

+0

我在函数中拥有这两个东西的原因是计算相当复杂,我需要在整个应用程序中的许多其他不同选择语句中得到结果。因此,对我来说编写功能只需一次,然后重新使用它就很有意义。我想我并不是唯一一个不喜欢重写相同代码的人。如果场景会像你指出的那样(只是简单的用CASE语句选择)来获得结果,我不会为它写一个函数。但事实并非如此。 – Trex 2010-08-13 08:33:31

+0

@特雷克斯:好的,那么。接受较慢的性能,然后避免针对基于集合的操作进行优化。这很简单 – gbn 2010-08-14 10:15:53

相关问题