Available in versions: Dev (3.19) | Latest (3.18) | 3.17 | 3.16 | 3.15 | 3.14 | 3.13 | 3.12 | 3.11 | 3.10 | 3.9

Filtering

Applies to ✅ Open Source Edition   ✅ Express Edition   ✅ Professional Edition   ✅ Enterprise Edition

The SQL standard specifies an optional FILTER clause, that can be appended to all aggregate functions including aggregated window functions. This is very useful, for example, to implement "pivot" tables, such as the following:

SELECT
  count(*),
  count(*) FILTER (WHERE TITLE LIKE 'A%'),
  count(*) FILTER (WHERE TITLE LIKE '%A%')
FROM BOOK
create.select(
         count(),
         count().filterWhere(BOOK.TITLE.like("A%")),
         count().filterWhere(BOOK.TITLE.like("%A%")))
      .from(BOOK)

Producing:

+-------+-------+-------+
| count | count | count |
+-------+-------+-------+
|     4 |     1 |     2 |
+-------+-------+-------+

Or, with GROUP BY:

SELECT
  AUTHOR_ID,
  count(*),
  count(*) FILTER (WHERE TITLE LIKE 'A%'),
  count(*) FILTER (WHERE TITLE LIKE '%A%')
FROM BOOK
GROUP BY AUTHOR_ID
create.select(
         BOOK.AUTHOR_ID,
         count(),
         count().filterWhere(BOOK.TITLE.like("A%")),
         count().filterWhere(BOOK.TITLE.like("%A%")))
      .from(BOOK)
      .groupBy(BOOK.AUTHOR_ID)

Producing:

+-----------+-------+-------+-------+
| AUTHOR_ID | count | count | count |
+-----------+-------+-------+-------+
|         1 |     2 |     1 |     1 |
|         2 |     2 |     0 |     1 |
+-----------+-------+-------+-------+

It is usually a good idea to calculate multiple aggregate functions in a single query, if this is possible, and FILTER helps here.

Only a few dialects implement native support for the FILTER clause. In all other databases, jOOQ emulates the clause using a CASE expression. Aggregate functions exclude NULL values from aggregation.

Dialect support

This example using jOOQ:

count().filterWhere(BOOK.TITLE.like("A%"))

Translates to the following dialect specific expressions:

-- ACCESS
count(SWITCH(BOOK.TITLE LIKE 'A%', 1))

-- ASE, AURORA_MYSQL, DB2, DERBY, EXASOL, HANA, INFORMIX, MARIADB, MEMSQL, MYSQL, ORACLE, REDSHIFT, SQLDATAWAREHOUSE, 
-- SQLSERVER, SYBASE, TERADATA, VERTICA
count(CASE
  WHEN BOOK.TITLE LIKE 'A%' THEN 1
END)

-- AURORA_POSTGRES, COCKROACHDB, DUCKDB, FIREBIRD, H2, HSQLDB, POSTGRES, SQLITE, TRINO, YUGABYTEDB
count(*) FILTER (WHERE BOOK.TITLE LIKE 'A%')

-- BIGQUERY
countif((BOOK.TITLE LIKE 'A%'))

-- SNOWFLAKE
count_if((BOOK.TITLE LIKE 'A%'))

(These are currently generated with jOOQ 3.19, see #10141), or translate your own on our website

References to this page

Feedback

Do you have any feedback about this page? We'd love to hear it!

The jOOQ Logo