2010-08-11 71 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

相關問題