документация правильная; то есть вы могли бы выполнить это утверждение:
select sum(wage) sum_of_all_wages
, count(1) count_of_all_records
from [dbo].[_abc]
having sum(wage) > 5
Причина, по которой ваше утверждение не работает, заключается в select *
, что означает выбор значения каждого столбца. Когда нет group by
, все записи агрегируются; то есть вы получаете только 1 запись в вашем наборе результатов, которая должна представлять каждую запись. Таким образом, вы можете * только включать значения, предоставленные применением агрегатных функций к вашим столбцам; не сами столбцы.
* конечно, вы также можете указать константы, поэтому select 'x' constant, count(1) cnt from myTable
будет работать.
Не так много вариантов использования, которые я могу придумать, где бы вы хотели использовать без группы, но, безусловно, это можно сделать, как показано выше.
NB. Если вы хотите, чтобы во всех строках зарплата была больше 5, вместо этого вы бы использовали выражение where
:
select *
from [dbo].[_abc]
where wage > 5
Точно так же, если вы хотите, чтобы сумма всех заработных плат превышала 5, вы можете сделать это
select sum(wage) sum_of_wage_over_5
from [dbo].[_abc]
where wage > 5
Или, если вы хотите сравнить сумму заработной платы, превышающей 5, с заработной платой:
select case when wage > 5 then 1 else 0 end wage_over_five
, sum(wage) sum_of_wage
from [dbo].[_abc]
group by case when wage > 5 then 1 else 0 end
См. примеры выполнения здесь .
Обновление на основе комментариев:
Вам нужно having
для использования агрегатных функций?
Нет. Вы можете запустить select sum(wage) from [dbo].[_abc]
. Когда агрегатная функция используется без предложения group by
, это похоже на группировку по константе; т.е. select sum(wage) from [dbo].[_abc] group by 1
.
Документация просто означает, что, хотя обычно у вас есть оператор having
с оператором group by
, можно исключить group by
/, в таких случаях оператор having
, такой как оператор select
, обработает ваш запрос так, как если бы вы указали group by 1
Какой смысл?
Трудно придумать много хороших вариантов использования, поскольку вы получаете только одну строку назад, а оператор having
является фильтром для этого.
Одним из вариантов использования может быть то, что вы пишете код для мониторинга ваших лицензий на некоторое программное обеспечение; если у вас меньше пользователей, чем на пользователя, все хорошо / вы не хотите видеть результат, так как вам все равно. Если у вас есть больше пользователей, вы хотите знать об этом. Э.Г.
declare @totalUserLicenses int = 100
select count(1) NumberOfActiveUsers
, @totalUserLicenses NumberOfLicenses
, count(1) - @totalUserLicenses NumberOfAdditionalLicensesToPurchase
from [dbo].[Users]
where enabled = 1
having count(1) > @totalUserLicenses
Разве выбор не имеет отношения к предложению has?
Да и нет. Наличие фильтра на ваших агрегированных данных. Выберите говорит, какие столбцы / информацию вернуть. Таким образом, вы должны спросить "как бы выглядел результат?" то есть, учитывая, что нам пришлось эффективно применять group by 1
для использования оператора having
, как SQL должен интерпретировать select *
? Поскольку в вашей таблице только один столбец, это будет означать select wage
; но у нас есть 5 строк, поэтому 5 различных значений wage
, и только 1 строка в результате, чтобы показать это.
Полагаю, вы могли бы сказать: «Я хочу вернуть все строки, если их сумма больше 5; в противном случае я не хочу возвращать какие-либо строки». Если бы ваше требование было достигнуто различными способами; один из которых будет:
select *
from [dbo].[_abc]
where exists
(
select 1
from [dbo].[_abc]
having sum(wage) > 5
)
Однако мы должны написать код для удовлетворения требований, а не ожидать, что код поймет наши намерения.
Еще один способ думать о having
- это выражение where
, применяемое к подзапросу. То есть Ваше оригинальное утверждение фактически гласит:
select wage
from
(
select sum(wage) sum_of_wage
from [dbo].[_abc]
group by 1
) singleRowResult
where sum_of_wage > 5
Это не запустится, потому что wage
недоступен для внешнего запроса; возвращается только sum_of_wage
.