Files
lancedb/docs/web/sql/window.mdx
T
Jack Ye fe651ae003 docs: seed the SQL reference from DataFusion 54, and cross-link it
The function catalogue is now real rather than a pointer. Scalar functions are
listed by taxonomy -- math, string, unicode, regex, date/time, array, map,
struct, crypto, type -- and the names come from what datafusion-functions 54
actually registers, not from what DataFusion documents on main. Aggregate and
window pages gain the same treatment.

Two things the audit corrected rather than copied.

SHOW TABLES does not work. DataFusion implements it over information_schema,
which this session does not enable, so it fails at plan time. It was documented
as working here, on the SHOW page and in three Manage tables; all four are
fixed, and the SQL overview now lists the absence alongside SHOW COLUMNS.

Prepared statements are a Flight SQL protocol feature, not a PREPARE statement.
A script carrying PREPARE ... AS SELECT will not run, while the same intent
expressed through a client will. The new page says so rather than copying
DataFusion's syntax.

Every section of the Documentation tab that has a SQL counterpart now links to
it -- 27 of 76 non-SQL pages, each pointing at the specific statement rather
than at the reference index.
2026-09-14 00:42:31 -07:00

101 lines
2.7 KiB
Plaintext

---
title: "Window functions"
sidebarTitle: "Window"
description: "Compute over a set of rows related to the current one, without collapsing them."
icon: chart-simple
keywords: ["window", "over", "partition by", "row_number", "rank", "lag", "lead"]
---
<Badge color="red">Enterprise</Badge> [SQL runs on a deployment.](/sql)
A window function computes across a set of rows related to the current one and
returns a value **per row**. That is the difference from
[aggregation](/sql/aggregation), which collapses the rows it covers.
```sql
SELECT
title,
score,
row_number() OVER (PARTITION BY category ORDER BY score DESC) AS rank
FROM documents
```
Every row survives; each one gains its rank within its category.
## The window {#window}
```sql
OVER (
[PARTITION BY expr [, ...]]
[ORDER BY expr [, ...]]
[ROWS | RANGE BETWEEN frame_start AND frame_end]
)
```
`PARTITION BY` splits the rows into independent groups. `ORDER BY` orders them
inside each partition -- required by the ranking functions, since a rank without
an order is meaningless. The frame clause narrows the window further, which is
how running totals and moving averages are expressed:
```sql
SELECT
created_at,
sum(amount) OVER (ORDER BY created_at ROWS UNBOUNDED PRECEDING) AS running_total,
avg(amount) OVER (ORDER BY created_at ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) AS trailing_7
FROM transactions
```
A `WINDOW` clause names a definition when several functions share one:
```sql
SELECT
row_number() OVER w,
lag(score) OVER w
FROM documents
WINDOW w AS (PARTITION BY category ORDER BY score DESC)
```
## The functions {#functions}
Registered in DataFusion 54.
**Ranking**
```text
row_number rank dense_rank percent_rank cume_dist ntile
```
**Offset and positional**
```text
lag lead first_value last_value nth_value
```
**Aggregates**
Any [aggregate function](/sql/aggregation#functions) used with `OVER` becomes a
window function — that is how running totals and moving averages are written.
## Deduplicating with a window {#dedup}
The common practical use: keep one row per key, chosen by some ordering. A
window ranks, and an outer query filters:
```sql
WITH ranked AS (
SELECT *, row_number() OVER (PARTITION BY doc_id ORDER BY version DESC) AS rn
FROM revisions
)
SELECT * FROM ranked WHERE rn = 1
```
The outer query is needed because a window function cannot appear in `WHERE` --
windows are computed after filtering, so the predicate would have nothing to
read.
<Note>
Window functions sort within each partition, so on a large table they are among
the more expensive things you can ask for. Filter first, and check the cost with
[Explain Analyze](/search/explain-analyze).
</Note>