A window function computes a value for each row from a set of related rows, defined by an OVER clause with an optional PARTITION BY, ORDER BY and frame. Unlike GROUP BY, it keeps every input row, which is what running totals, rankings (ROW_NUMBER, RANK, DENSE_RANK) and row-to-row comparisons (LAG, LEAD) need.
In an FDE interview
As of September 2026, Rippling’s Manager, Forward Deployed Engineering posting asks for SQL and data modeling alongside a general-purpose language. Source 1Manager, Forward Deployed EngineeringPublisherRippling (ats.rippling.com)Source typecompany job posting One Blind commenter reported, in November 2025, that their Palantir process began with an online assessment of coding, SQL and API questions. Source 2Palantir FDSE Interview (Blind thread)PublisherBlindSource typecandidate report on Blind In a SQL exercise, window functions sit behind running totals and top-N-per-group questions, and the detail to get right is the frame.
With an ORDER BY and no frame, the default is RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW, so rows that tie on the ordering column are peers and get the same running total (SQLite, window functions); say so. For a per-row sum, write ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW and add a tiebreaker so the order is unique (ORDER BY order_date, order_id); with ROWS and ties, the running total depends on the order the engine happens to pick. With no ORDER BY at all, the frame is the whole partition, so SUM(x) OVER (PARTITION BY k) is the group total on every row.
Say which ranking function you chose and what it does with ties, and filter on a rank in an outer query or CTE, because a window function cannot appear in WHERE. Snowflake, Databricks, BigQuery and DuckDB also accept QUALIFY ROW_NUMBER() OVER (...) = 1; SQLite and PostgreSQL do not, so write the CTE there.
The running total question practices the frame on a running total per customer by day.
Related: gaps and islands.