Add a per-aggregate WHERE condition to filter the rows included in that specific aggregate, without a separate subquery.
PostgreSQL FILTER clause on aggregate functions computes the aggregate only for rows matching a WHERE-like condition, without needing a GROUP BY. More readable than wrapping aggregates in CASE, especially when filtering is inherently about the aggregate rather than the row.
| Database System | Support Status | Since Version | Notes |
|---|---|---|---|
| MySQL | ✗ Not Supported | — | Not supported. Use SUM(CASE WHEN cond THEN 1 ELSE 0 END) or COUNT(CASE WHEN cond THEN 1 END) as a workaround. |
| PostgreSQL | ✓ Supported | 9.4 | Full support on all aggregate functions including COUNT, SUM, AVG, array_agg, etc. Also works on window functions when the window function is itself an aggregate. |
| SQL Server | ✓ Supported | 2022 | FILTER clause added in SQL Server 2022 (compatibility level 130+). Works with standard aggregates. |
| Oracle | ✗ Not Supported | — | Not supported. Use CASE expressions inside aggregates. |
| SQLite | ✓ Supported | 3.30.0 | FILTER clause added in SQLite 3.30.0 (October 2019). Works with all built-in aggregates. |
Defined in the SQL standard (ISO/IEC 9075:2003). Oracle is the notable holdout. The CASE workaround is portable across all engines but significantly more verbose.
Not supported. Use SUM(CASE WHEN cond THEN 1 ELSE 0 END) or COUNT(CASE WHEN cond THEN 1 END) as a workaround.
Full support on all aggregate functions including COUNT, SUM, AVG, array_agg, etc. Also works on window functions when the window function is itself an aggregate.
FILTER clause added in SQL Server 2022 (compatibility level 130+). Works with standard aggregates.
Not supported. Use CASE expressions inside aggregates.
FILTER clause added in SQLite 3.30.0 (October 2019). Works with all built-in aggregates.