QUALIFY
clause
The QUALIFY
clause is used to filter the results of window functions. This filtering of results is similar to how the HAVING
clause filters the results of aggregate functions used in queries with the GROUP BY
clause.
The QUALIFY
clause avoids the need for a subquery or expression with WITH
to perform this filtering (just as HAVING
avoids subqueries).
Syntax
QUALIFY <predicate>
The general form of expressions with QUALIFY
usually looks like this (some variations in order are allowed):
SELECT <column_list>
FROM <data_source>
[GROUP BY ...]
[HAVING ...]
QUALIFY <predicate>
[ ... ]
Parameters
-
<column_list>
List ofSELECT
clause.
-
<data_source>
The data source is usually a table, but it can be another data source similar to a table, such as a view, a custom table function, etc.
-
<predicate>
A predicate is an expression that filters the result after evaluating aggregate and window functions. A predicate is similar to theHAVING
clause, but without theHAVING
keyword itself. In addition, the predicate may contain window functions.
Examples
Let’s create and fill the table:
CREATE TABLE qt (i INTEGER, p CHAR(1), o INTEGER);
INSERT INTO qt (i, p, o) VALUES
(1, 'A', 1),
(2, 'A', 2),
(3, 'B', 1),
(4, 'B', 2);
This query uses a nested structure rather than QUALIFY
:
SELECT *
FROM (
SELECT i, p, o,
ROW_NUMBER() OVER (PARTITION BY p ORDER BY o) AS row_num
FROM qt
)
WHERE row_num = 1;
+---+---+---+---------+
| I | P | O | ROW_NUM |
|---+---+---+---------|
| 1 | A | 1 | 1 |
| 3 | B | 1 | 1 |
+---+---+---+---------+
And this query uses QUALIFY
:
SELECT i, p, o
FROM qt
QUALIFY ROW_NUMBER() OVER (PARTITION BY p ORDER BY o) = 1;
+---+---+---+
| I | P | O |
|---+---+---|
| 1 | A | 1 |
| 3 | B | 1 |
+---+---+---+
We use QUALIFY
to refer to window functions that are in the SELECT
clause:
SELECT i, p, o, ROW_NUMBER() OVER (PARTITION BY p ORDER BY o) AS row_num
FROM qt
QUALIFY row_num = 1;
+---+---+---+---------+
| I | P | O | ROW_NUM |
|---+---+---+---------|
| 1 | A | 1 | 1 |
| 3 | B | 1 | 1 |
+---+---+---+---------+
A QUALIFY
clause can also be combined with aggregate functions and may contain subqueries:
SELECT c2, SUM(c3) OVER (PARTITION BY c2) AS r
FROM t1
WHERE c3 < 4
GROUP BY c2, c3
HAVING sum(c1) > 3
QUALIFY r IN (
SELECT min(c1)
FROM test
GROUP BY c2
HAVING min(c1) > 3);