HTML CSS Bootstrap JavaScript jQuery MySQL PHP Data Mining

MySQL HAVING Clause

The HAVING clause filters the results after GROUP BY has formed its groups. It is the equivalent of WHERE, but for grouped data. While WHERE cannot reference aggregate functions like COUNT() or SUM(), HAVING can — because by the time HAVING runs, the groups and their aggregates have already been calculated.


HAVING vs WHERE — The Key Difference

ClauseFiltersCan use aggregate functions?
WHERE Individual rows before grouping No
HAVING Groups after grouping Yes

Syntax

SELECT column, aggregate_function(column)
FROM table_name
WHERE condition
GROUP BY column
HAVING aggregate_condition
ORDER BY column;

Sample Table

idnamecategorypricequantity_sold
1LaptopElectronics55000.005
2PhoneElectronics25000.0012
3T-ShirtClothing800.0040
4HeadphonesElectronics3500.0018
5JeansClothing2200.0022
6TabletElectronics35000.008
7JacketClothing4500.0015

HAVING with COUNT()

Show only categories that contain more than 3 products:

SELECT category, COUNT(*) AS total
FROM products
GROUP BY category
HAVING COUNT(*) > 3;
categorytotal
Electronics4

Clothing has only 3 products, so it is excluded. Electronics has 4 and passes the filter.


HAVING with SUM()

Show only categories where the total units sold exceed 50:

SELECT category, SUM(quantity_sold) AS total_sold
FROM products
GROUP BY category
HAVING SUM(quantity_sold) > 50;
categorytotal_sold
Clothing77

HAVING with AVG()

Find categories where the average price is above 10,000:

SELECT category, ROUND(AVG(price), 2) AS avg_price
FROM products
GROUP BY category
HAVING AVG(price) > 10000;
categoryavg_price
Electronics29625.00

Combining WHERE and HAVING

Use both in the same query: WHERE filters individual rows first, then GROUP BY forms groups, and finally HAVING filters those groups:

-- Among products priced above 1000 only,
-- show categories with more than 2 such products
SELECT category, COUNT(*) AS total
FROM products
WHERE price > 1000
GROUP BY category
HAVING COUNT(*) > 2;
Remember the execution order: WHEREGROUP BYHAVINGORDER BYLIMIT. WHERE filters rows before grouping; HAVING filters groups after.

HAVING with AND / OR

You can combine multiple conditions in HAVING using AND and OR:

-- Categories with more than 2 products AND average price above 5000
SELECT category, COUNT(*) AS total, ROUND(AVG(price), 2) AS avg_price
FROM products
GROUP BY category
HAVING COUNT(*) > 2 AND AVG(price) > 5000;

Key Points to Remember

  • HAVING filters groups after GROUP BY — it is the post-grouping equivalent of WHERE.
  • WHERE cannot use aggregate functions; HAVING can.
  • You can use both WHERE and HAVING in the same query — they serve different stages.
  • Execution order: WHERE (rows) → GROUP BY (groups) → HAVING (filter groups) → ORDER BY.
  • Combine multiple conditions in HAVING using AND and OR.
What's next? You have completed the Aggregate Functions section. The next section covers Joins — starting with a Joins Introduction that explains how to combine data from multiple tables in a single query.