All Products
Search
Document Center

KEEP

Last Updated: Sep 29, 2021

The KEEP function operates on the values from a set of rows that rank based on a given sorting rule and returns the first or last value. As an aggregate function, the KEEP function operates on all rows and returns a single output row. As an analytic function, the KEEP function divides the query result set into groups based on one or more expressions in the query_partition_clause.

The KEEP function must be used in conjunction with the MIN, MAX, SUM, AVG, COUNT, VARIANCE or STDDEV function.

Syntax

KEEP (DENSE_RANK {FIRST | LAST} ORDER BY expr [ DESC | ASC ] [ NULLS { FIRST | LAST } ] [, expr [ DESC | ASC ] [ NULLS { FIRST | LAST } ]]... )
   [ OVER ( [query_partition_clause] ) ]

To use it as an analytic function, you need to use the complete syntax of the window function to operate on a set of rows and return multiple values. To use it as an aggregate function, it operates on a set of rows and returns a single value. You do not need to add the OVER keyword.

Parameters

Parameter

Description

OVER

You can use the OVER clause to define a window over the data on which the function operates.

expr

An expression of any type. Null values in the measure column are ignored.

Return type

This function returns data of the same data type as that of the measure column.

Examples

Using KEEP as an analytic function

Execute the following statement to create Table employees and insert data into it:

CREATE TABLE employees (department_id INT,manager_id INT,last_name varchar(50),hiredate varchar(50),SALARY INT);
INSERT INTO employees VALUES(30, 100, 'Raphaely', '2017-07-01', 1700);
INSERT INTO employees VALUES(30, 100, 'De Haan', '2018-05-01',11000);      
INSERT INTO employees VALUES(40, 100, 'Errazuriz', '2017-07-21', 1400);
INSERT INTO employees VALUES(50, 100, 'Hartstein', '2019-10-05',14000);     
INSERT INTO employees VALUES(50, 100, 'Raphaely', '2017-07-22', 1700);
INSERT INTO employees VALUES(50, 100, 'Weiss',  '2019-10-05',13500);     
INSERT INTO employees VALUES(90, 100, 'Russell', '2019-07-11', 13000);
INSERT INTO employees VALUES(90,100, 'Partners',  '2018-12-01',14000);

Assume that, for each department, you want to sort the employees by their salaries and calculate the sum of the salary of the first employee. Then, you want to sort the employees by the hire date and calculate the sum of the salary of the last employee. Execute the following statement:

SELECT last_name, department_id, salary,
       SUM(salary) KEEP (DENSE_RANK FIRST ORDER BY salary)
         OVER (PARTITION BY department_id) "Worst",
       SUM(salary) KEEP (DENSE_RANK LAST ORDER BY HIREDATE)
         OVER (PARTITION BY department_id) "Best"
   FROM employees
   ORDER BY department_id, salary, last_name;

Result:

+-----------+---------------+--------+-------+-------+
| LAST_NAME | DEPARTMENT_ID | SALARY | Worst | Best  |
+-----------+---------------+--------+-------+-------+
| Raphaely  |            30 |   1700 |  1700 | 11000 |
| De Haan   |            30 |  11000 |  1700 | 11000 |
| Errazuriz |            40 |   1400 |  1400 |  1400 |
| Raphaely  |            50 |   1700 |  1700 | 27500 |
| Weiss     |            50 |  13500 |  1700 | 27500 |
| Hartstein |            50 |  14000 |  1700 | 27500 |
| Russell   |            90 |  13000 | 13000 | 13000 |
| Partners  |            90 |  14000 | 13000 | 13000 |
+-----------+---------------+--------+-------+-------+
8 rows in set (0.01 sec)

Using KEEP as an aggregate function

Execute the following statement to create Table employees and insert data into it:

CREATE TABLE employees (department_id INT,manager_id INT,last_name varchar(50),hiredate varchar(50),SALARY INT);
INSERT INTO employees VALUES(30, 100, 'Raphaely', '2017-07-01', 1700);
INSERT INTO employees VALUES(30, 100, 'De Haan', '2018-05-01',11000);      
INSERT INTO employees VALUES(40, 100, 'Errazuriz', '2017-07-21', 1400);
INSERT INTO employees VALUES(50, 100, 'Hartstein', '2019-10-05',14000);     
INSERT INTO employees VALUES(50, 100, 'Raphaely', '2017-07-22', 1700);
INSERT INTO employees VALUES(50, 100, 'Weiss',  '2019-10-05',13500);     
INSERT INTO employees VALUES(90, 100, 'Russell', '2019-07-11', 13000);
INSERT INTO employees VALUES(90,100, 'Partners',  '2018-12-01',14000);

Assume that you want to sort the employees by their salaries and calculate the sum of the salary of the first employee. Then, you want to sort the employees by the hire date and calculate the sum of the salary of the last employee. Execute the following statement:

SELECT 
       SUM(salary) KEEP (DENSE_RANK FIRST ORDER BY salary) "Worst",
       SUM(salary) KEEP (DENSE_RANK LAST ORDER BY HIREDATE) "Best"
  FROM employees;

Result:

+-------+-------+
| Worst | Best  |
+-------+-------+
|  1400 | 27500 |
+-------+-------+
1 row in set (0.00 sec)