Агрегатная функция в SQL Where-предложение
в тесте в университете возник вопрос; Можно ли использовать агрегатную функцию в SQL WHERE предложения.
Я всегда думал, что это невозможно и я тоже не могу найти ни одного примера, как это будет возможно. Но мой ответ был помечен ложь и теперь я хочу знать, в каких случаях можно использовать агрегатную функцию в WHERE. Также, если это невозможно, было бы неплохо получить ссылку на спецификацию, где она описана.
6 ответов:
вы не упомянули СУБД. Предполагая, что вы используете MS SQL-Server, я нашел сообщение об ошибке T-SQL, которое не требует пояснений:
"агрегат может не отображаться в Где предложение, если оно не находится в a подзапрос, содержащийся в предложении HAVING или список выбора, а столбец является агрегированный-это внешняя ссылка"
http://www.sql-server-performance.com/
и пример, что это возможно в подзапросе.
показать всех клиентов и наименьший заказ для тех, у кого есть 5 или более заказов (и NULL для других):
SELECT a.lastname , a.firstname , ( SELECT MIN( o.amount ) FROM orders o WHERE a.customerid = o.customerid AND COUNT( a.customerid ) >= 5 ) AS smallestOrderAmount FROM account a GROUP BY a.customerid , a.lastname , a.firstname ;
обновление.
выше работает как в SQL-Server и MySQL, но он не возвращает результат, который я ожидал. Следующий-ближе. Я думаю, это связано с тем, что поле
customerid, сгруппировано и используется в соединении запрос-подзапрос в первом случае первичный ключ внешней таблицы, а во втором случае это не.показать все идентификаторы клиентов и количество заказов для тех, у кого есть 5 или более заказов (и NULL для других):
SELECT o.customerid , ( SELECT COUNT( o.customerid ) FROM account a WHERE a.customerid = o.customerid AND COUNT( o.customerid ) >= 5 ) AS cnt FROM orders o GROUP BY o.customerid ;
наличие похоже на то, где с агрегатными функциями, или вы можете использовать подзапрос.
select EmployeeId, sum(amount) from Sales group by Employee having sum(amount) > 20000или
select EmployeeId, sum(amount) from Sales group by Employee where EmployeeId in ( select max(EmployeeId) from Employees)
вы не можете использовать агрегат непосредственно в предложении WHERE; вот для чего нужны предложения.
вы можете использовать подзапрос, который содержит агрегат в предложении WHERE.
обновленный запрос:
select id from t where id < (select max(id) from t);он выберет все, кроме последней строки из таблицы t.
SELECT COUNT( * ) FROM agents HAVING COUNT(*)>3;смотрите дополнительную ссылку ниже:
http://www.w3resource.com/sql/aggregate-functions/count-having.php#sthash.90csRM4I.dpuf][1] позвони мне, если любой запрос:85110 51548
http://www.w3resource.com/sql/aggregate-functions/count-having.php
другое решение -переместите агрегатную функцию в скалярную пользовательскую функцию
Создайте Свою Функцию:
CREATE FUNCTION getTotalSalesByProduct(@ProductName VARCHAR(500)) RETURNS INT AS BEGIN DECLARE @TotalAmount INT SET @TotalAmount = (select SUM(SaleAmount) FROM Sales where Product=@ProductName) RETURN @TotalAmount ENDиспользовать функцию в предложении Where
SELECT ProductName, SUM(SaleAmount) AS TotalSales FROM Sales WHERE dbo.getTotalSalesByProduct(ProductName) > 1000 GROUP BY Productссылки:
надеюсь кому-нибудь поможет.
Comments