Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL: How to filter after aggregation?

Tags:

It is very easy to remove values that you don't want aggregated.

For instance:

SELECT department, SUM(sales) as "Total sales" FROM order_details GROUP BY department HAVING SUM(sales) > 1000; 

Which will exclude all sales with a value less than or equal to 1000 from the summing aggregation.

But how do you filter after the aggregation?

E.g. WHERE ("Total sales"> 15000)

Edit: Ironically I was only including HAVING SUM(sales) > 1000; in order to prevent confusion about the type of query required; because I'm not actually interested in excluding items from the summing, just the returned results! Thanks, despite confusion!

like image 358
Stumbler Avatar asked Apr 02 '13 15:04

Stumbler


People also ask

How do you filter aggregates?

To filter records using the aggregate function (the function SUM from earlier), use the HAVING clause. To calculate the sum of values for each group of rows, use the aggregation SUM function.

How can you filter the rows after GROUP BY clause?

After Grouping the data, you can filter the grouped record using HAVING Clause. HAVING Clause returns the grouped records which match the given condition. You can also sort the grouped records using ORDER BY. ORDER BY used after GROUP BY on aggregated column.

Which clause is used to filter aggregated data?

The filter clause extends aggregate functions ( sum , avg , count , …) by an additional where clause. The result of the aggregate is built from only the rows that satisfy the additional where clause too.


1 Answers

The query you have is actually doing what you want and not what you expressed in the question. If you want to exclude all sales with a value less than 1000, you should use WHERE sales > 1000. But with HAVING SUM(sales) > 1000 the filtering is actually done after the aggregation.

Writing a sub-query and adding another SELECT WHERE on top of the original query is redundant.

Please see fiddle for clarification.

#Query1  SELECT department, SUM(sales) as Total FROM order_details GROUP BY department HAVING Total > 40;  #Query 2  SELECT department, SUM(sales) as Total FROM order_details GROUP BY department HAVING  SUM(sales) > 40;  #Query 3  SELECT department, SUM(sales) as Total FROM order_details WHERE sales > 40 GROUP BY department;  #Query 1 and 2 are the same, filtering after aggregation #Query 3 is filtering before aggregation 
like image 113
jurgenreza Avatar answered Sep 22 '22 15:09

jurgenreza