Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Aggregate function in SQL WHERE-Clause

Tags:

sql

In a test at university there was a question; is it possible to use an aggregate function in the SQL WHERE clause.

I always thought this isn't possible and I also can't find any example how it would be possible. But my answer was marked false and now I want to know in which cases it is possible to use an aggregate function in the WHERE. Also if it isn't possible it would be nice to get a link to the specification where it is described.

like image 862
n3on Avatar asked Jun 11 '11 23:06

n3on


People also ask

Why we Cannot use aggregate function in WHERE clause?

We cannot use the WHERE clause with aggregate functions because it works for filtering individual rows. In contrast, HAVING can works with aggregate functions because it is used to filter groups.

Can we use WHERE clause with GROUP BY?

GROUP BY Clause is utilized with the SELECT statement. GROUP BY aggregates the results on the basis of selected column: COUNT, MAX, MIN, SUM, AVG, etc. GROUP BY returns only one result per group of data. GROUP BY Clause always follows the WHERE Clause.

Can we use aggregate function in subquery?

It turned out that subqueries are not allowed in aggregate functions.


2 Answers

HAVING is like WHERE with aggregate functions, or you could use a subquery.

select EmployeeId, sum(amount) from Sales group by Employee having sum(amount) > 20000 

Or

select EmployeeId, sum(amount) from Sales group by Employee where EmployeeId in (     select max(EmployeeId) from Employees) 
like image 116
Jason Goemaat Avatar answered Oct 13 '22 04:10

Jason Goemaat


You haven't mentioned the DBMS. Assuming you are using MS SQL-Server, I've found a T-SQL Error message that is self-explanatory:

"An aggregate may not appear in the WHERE clause unless it is in a subquery contained in a HAVING clause or a select list, and the column being aggregated is an outer reference"

http://www.sql-server-performance.com/


And an example that it is possible in a subquery.

Show all customers and smallest order for those who have 5 or more orders (and NULL for others):

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 ; 

UPDATE.

The above runs in both SQL-Server and MySQL but it doesn't return the result I expected. The next one is more close. I guess it has to do with that the field customerid, GROUPed BY and used in the query-subquery join is in the first case PRIMARY KEY of the outer table and in the second case it's not.

Show all customer ids and number of orders for those who have 5 or more orders (and NULL for others):

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 ; 
like image 35
Tim Schmelter Avatar answered Oct 13 '22 06:10

Tim Schmelter