# HAVING

`HAVING` filters the groups produced by an aggregate query. It can use aggregate expressions, such as `sum(amount) > 100`, because it runs after the group has been calculated.

Use [`WHERE`](https://coordinatordb.com/docs/reference/statements/select/where) to filter individual input rows before aggregation. A query can use both clauses.

## Syntax

```text
SELECT grouping_key, aggregate_function(value)
FROM source
[WHERE row_condition]
GROUP BY grouping_key
HAVING aggregate_condition
```

A group is retained only when the condition is SQL true. False and `NULL` conditions remove the group.

## Example

### Regions with enough paid revenue

`WHERE` excludes pending orders; `HAVING` then excludes regions whose paid total is too small:

```sql
CREATE TABLE orders (region TEXT, status TEXT, amount INTEGER);
INSERT INTO orders VALUES ('East', 'paid', 60),
           ('East', 'paid', 70),
           ('West', 'paid', 40),
           ('West', 'pending', 200);
```

```sql
SELECT region, sum(amount) AS paid_total
FROM orders
WHERE status = 'paid'
GROUP BY region
HAVING sum(amount) >= 100
ORDER BY region
FORMAT csv;
```

```text
"East",130
```

See [`GROUP BY`](https://coordinatordb.com/docs/reference/statements/select/group-by) for grouping expressions and [aggregate functions](https://coordinatordb.com/docs/reference/functions/aggregate-functions) for the calculations available in `HAVING`.
