Как избежать вызова функции T-SQL чаще, когда требуются комбинированные результаты? - PullRequest
1 голос
/ 11 августа 2010

У меня есть две скалярные функции T-SQL, которые выполняют вычисления для больших объемов данных (занимают «много» времени) и возвращают значение, например, CalculateAllIncomes (EmployeeID) и CalculateAllExpenditures (EmployeeID).

Я запускаю оператор выбора, который вызывает их и возвращает результаты для каждого сотрудника. Мне также нужно, чтобы баланс каждого сотрудника рассчитывался как AllIncomes-AllExpenditures.

У меня есть функция GetBalance (EmployeeID), которая вызывает две вышеупомянутые функции и возвращает результат {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. Это так? И если так, что может быть обходным путем в этом случае? Спасибо за любые предложения.

1 Ответ

5 голосов
/ 11 августа 2010

Забудьте о вызовах функций: вы, вероятно, можете сделать все это одним обычным запросом.

Неправильное использование вызовов функций (попытка инкапсуляции OO) вынуждает вас в этой ситуации. Кроме того, если у вас есть GetBalance (EmployeeID) на строку в таблице Employee, то вы выполняете КУРСОР по таблице. И вы теперь усугубили это несколькими вызовами.

Что вам нужно, это что-то вроде этого:

;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 

Однажды я сократил запрос с выходных до менее чем за секунду, исключив такого рода ОО-рассуждения из агрегатного запроса на основе стандартного набора болот.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...