Skip to main content
CockroachDB supports the application of a function over a subset of the rows returned by a selection query. Such a function is known as a window function, and it allows you to compute values by operating on more than one row at a time. The subset of rows a window function operates on is known as a window frame. For a complete list of supported window functions, see .
All aggregate functions can also be used as window functions. For more information, see the Examples below.

Window definitions

Window frames are defined in or .

Syntax

window_definition syntax diagram

Parameters

ParameterDescription
window_nameThe name of the new window frame.
opt_existing_window_nameAn optional name of an existing window frame, defined in a different window definition.
opt_partition_clauseAn optional PARTITION BY clause.
opt_sort_clauseAn optional ORDER BY clause. See for details.
opt_frame_clauseAn optional frame clause, which contains a frame boundary and/or an EXCLUDE clause.

How window functions work

At a high level, window functions work by:
  1. Creating a “virtual table” using a selection query.
  2. Splitting that table into window frames with window definitions. You can define window frames in an , directly after the window function, or in a , as a part of the selection query.
  3. Applying the window function to each of the window frames.
For example, consider a query where the window frames are defined for each window function call:
Its operation can be described as follows (numbered steps listed here correspond to the numbers in the diagram below):
  1. The outer SELECT DISTINCT(city) ... FROM rides creates a “virtual table” on which the window functions will operate.
  2. The window function SUM(revenue) OVER () operates on a window frame containing all rows of the query output.
  3. The window function SUM(revenue) OVER (PARTITION BY city) operates on several window frames in turn; each frame contains the revenue columns for a different city (Amsterdam, Boston, L.A., etc.).
Window function diagram

Caveats

The most important part of working with window functions is understanding what data will be in the frame that the window function will be operating on. By default, the window frame includes all of the rows of the partition. If you order the partition, the default frame includes all rows from the first row in the partition to the current row. In other words, adding an ORDER BY clause when you create the window frame (e.g., PARTITION BY x ORDER by y) has the following effects:
  • It makes the rows inside the window frame ordered.
  • It changes what rows the function is called on - no longer all of the rows in the window frame, but a subset between the “first” row and the current row.
Another way of saying this is that you can run a window function on either:
  • All rows in the window frame created by the PARTITION BY clause, e.g., SELECT f(x) OVER () FROM z.
  • A subset of the rows in the window frame if the frame is created with SELECT f(x) OVER (PARTITION BY x ORDER BY y) FROM z.
Because of this, you should be aware of the behavior of any aggregate function you use as a window function. If you are not seeing results you expect from a window function, this behavior may explain why. You may need to specify the frame boundaries explicitly in the window definition.
If you are running separate window functions over the same window frame, you can define the window frame once in a WINDOW clause, and then refer to the window by its name when you call the window function. For an example, see Customers taking the most rides and generating the most revenue.

Examples

Setup

The following examples use MovR, a fictional vehicle-sharing application, to demonstrate CockroachDB SQL statements. For more information about the MovR example application and dataset, see . To follow along, run with the --geo-partitioned-replicas flag. This command opens an interactive SQL shell to a temporary, 9-node in-memory cluster with the movr database.

Customers taking the most rides

To see which customers have taken the most rides, run:

Customers generating the most revenue

To see which customers have generated the most revenue, run:

Add row numbers to query output

To add row numbers to the output, kick the previous query down into a subquery and run the row_number() window function.

Customers taking the most rides and generating the most revenue

To see which customers have taken the most rides while generating the most revenue, run:
Note that in the query above, a WINDOW clause defines the window frame, and the OVER clauses reuse the window frame.

Customers with the highest average revenue per ride

To see which customers have the highest average revenue per ride, run:

Customers with the highest average revenue per ride, given ten or more rides

To see which customers have the highest average revenue per ride, given that they have taken at least 10 rides, run:

Total number of riders, and total revenue

To find out the total number of riders and total revenue generated thus far by the app, run:

How many vehicles of each type

How much revenue per city

See also