CSV Window Functions
Add SQL-style window columns to a CSV without collapsing rows: running total, moving average, lag/lead, rank, dense_rank, and row_number — grouped by partition and ordered however you like.
About this CSV window-function tool
Window functions compute a value across a set of rows that are related to the
current row, without collapsing those rows the way GROUP BY does. This tool
brings the SQL OVER (PARTITION BY … ORDER BY …) idea to a plain CSV: every input
row is kept, and one new column is appended with the window result.
Pick a function, choose the value column by header name (for example sales) or
1-based index (for example 3), and optionally partition and order the rows:
region,day,sales
W,2,5
E,1,10
W,1,3
E,2,20
A running total of sales, partitioned by region and ordered by day,
produces one cumulative column, with rows grouped by partition:
region,day,sales,running_total_sales
W,1,3,3
W,2,5,8
E,1,10,10
E,2,20,30
The functions
- running_total — cumulative sum of the value column within each partition.
- moving_average — trailing mean over the last
windowrows (including the current row); early rows average whatever rows exist so far. - lag / lead — the value
offsetrows before (lag) or after (lead) the current row; rows with no neighbour are left blank. - rank — position by value within the partition. Tied values share a rank and the next rank skips (1, 1, 3, 4).
- dense_rank — like rank, but with no gaps after ties (1, 1, 2, 3).
- row_number — a 1-based counter within each partition; needs no value column.
Partitions and order
partition_by splits the rows into independent windows — one per distinct
combination of the listed columns — so a running total restarts for each region
and a rank is computed group by group. order_by sorts rows within each partition
before the function runs, which is what makes a running total or lag meaningful.
Turn on Descending to reverse the sort and to rank the largest value first.
Numbers are detected automatically; blank or non-numeric cells are skipped by the numeric functions (running total, moving average) rather than treated as zero.
Everything runs locally in your browser. Your CSV data is never uploaded.
FAQ
What is the difference between rank and dense_rank?
Both give tied values the same rank. rank then leaves a gap — two values tied
for 1st are followed by 3rd (1, 1, 3, 4). dense_rank never leaves gaps, so the
next value is 2nd (1, 1, 2, 3). Use row_number when you want every row to get a
distinct number even on ties.
How does the moving average handle the first few rows?
The window is trailing and includes the current row, so with window=3 the first
row averages just itself, the second averages the first two, and from the third
row on it averages the current row plus the two before it. Non-numeric cells in the
frame are ignored, so a blank value does not drag the average toward zero.
Do I need to sort my CSV first?
No. Set order_by to the column that defines the sequence (such as a date or day
number) and the tool sorts each partition for you before computing. Leave
order_by empty to use the rows in their existing order. The output rows are
grouped by partition and follow the order you chose.
Can I compute a window per group, like per customer or per region?
Yes. Put the grouping column(s) in partition_by — for example region, or
region,category for a combined key. Each distinct combination becomes its own
window, so running totals restart and ranks are computed within each group
independently.
Why does the tool require a header row?
Columns are selected by header name (with 1-based index as a fallback), and the
appended column needs a header too. Keep the first row as your header. You can
still reference columns by number, such as 3, if your headers are not
descriptive.
Developer & Automation Access
Run it from the terminal
Same engine as this page, headless — via the gizza CLI:
gizza tool csv-window-functions "region,day,sales
W,1,3
W,2,5
E,1,10
E,2,20"New to the CLI? Get gizza →
Open it by URL
Pre-fill and auto-run this tool with query parameters — the names match the API/CLI:
https://gizza.ai/tools/csv-window-functions/?data=region%2Cday%2Csales%0AW%2C1%2C3%0AW%2C2%2C5%0AE%2C1%2C10%0AE%2C2%2C20&function=running_total&column=sales&partition_by=region&order_by=day&window=3&offset=1&output_column=running_total_sales&descending=true&has_header=true&delimiter=%2CMachine-readable descriptor: tool.json — title + parameters JSON Schema for agents.
