#sql #sql-server #tsql
#sql #sql-сервер #tsql
Вопрос:
У меня есть 4 отдельные пользовательские функции, которые мне нужно вызвать на основе значения другого столбца (состояния). Я могу заставить ее работать, когда я размещаю пользовательскую функцию после ВЫБОРА, однако мне нужно, чтобы она была размещена после того, как.
Вот код:
SELECT Fname, Lname, id, State, TotalWedThurMins, StCode
FROM dbo.AnnualRegCredits
GROUP BY Fname, Lname, id, State, TotalWedThurMins, StCode
HAVING (State = 'HI')
AND (dbo.roundnearestquarter(SUM(TotalWedThurMins)) > 0)
Есть предложения?
Комментарии:
1. Можете ли вы объяснить проблему более подробно?
2. Я думаю, вам следует изменить
HAVING (State = 'HI')
наWHERE (State = 'HI')
.3. да, каждое состояние должно округляться по-разному. ‘HI’ должно быть округлено до ближайшей четверти (.25). Время должно быть округлено до ближайшего получаса (.5). У меня есть все функции, созданные и работающие, но я застрял, пытаясь заставить их соответствовать каждому состоянию на мой взгляд. Имеет смысл?
Ответ №1:
Конечно
НАЛИЧИЕ предназначено для фильтрации после агрегирования (например, после ГРУППИРОВАНИЯ ПО). SUM(TotalWedThurMins)
является агрегированным. Таким образом, udf, использующий SUM в качестве анализатора, переходит в HAVING not WHERE .
SUM(TotalWedThurMins)
не определено и не имеет смысла в предложении WHERE
Однако, State
не агрегируется и может быть в предложении WHERE .
Итак, это выглядит следующим образом. Но зачем ГРУППИРОВАТЬ ПО, а затем суммировать TotalWedThurMins
? Возможно, вам нужно предложение OVER для управления обоими … (не уверен, что это допустимый синтаксис)
SELECT Fname, Lname, id, State, TotalWedThurMins, StCode
FROM dbo.AnnualRegCredits
WHERE (State = 'HI')
GROUP BY Fname, Lname, id, State, TotalWedThurMins, StCode
HAVING (dbo.roundnearestquarter(SUM(TotalWedThurMins) OVER ()) > 0)
Альтернативная формулировка с использованием OVER и CTE:
WITH CTE AS
(
SELECT Fname, Lname, id, State, TotalWedThurMins, StCode,
SUM(TotalWedThurMins) OVER () AS SumTotalWedThurMins
FROM dbo.AnnualRegCredits
WHERE State = 'HI'
)
SELECT
Fname, Lname, id, State, TotalWedThurMins, StCode
FROM
CTE
WHERE
dbo.roundnearestquarter(SumTotalWedThurMins) > 0
Комментарии:
1. Спасибо, это сработает, но мне нужно что-то другое. Я разместил неверный код. Приведенный ниже код работает для двух состояний (HI и FL). Однако мне нужна другая функция для MD. Как мне вызвать другую функцию в том же представлении: ВЫБЕРИТЕ Fname, Lname, id, State, dbo.GetRoundDownNearestQuarter(TotalWedThurMins) КАК Expr1, StCode ИЗ dbo. Ежегодные учетные записи, ГДЕ (State = ‘HI’) ИЛИ (State = ‘FL’) ГРУППИРУЮТСЯ По Fname, Lname, id, State, TotalWedThurMins, StCode
2. Отличное объединение, все сработало! Спасибо! Как обычно, простые вещи никогда не приходят на ум первыми!
Ответ №2:
Вы также можете использовать оператор APPLY, вот ссылка на хорошую статью, объясняющую использование и опции. Оператор APPLY позволяет присоединять таблицы к определенным типам функций.