🪟 Windows TippsThe Gemini desktop app is now available for Windows(11.09.2026 um 17:06 Uhr)
🪟 Windows TippsSetting up live captions stuck in Windows 11(14.09.2026 um 16:31 Uhr)
🕵️ SicherheitslückenBurn Out, Or Fade Away(14.09.2026 um 14:25 Uhr)
🪟 Windows TippsWindows 11's latest update broke my speakers, and I'm not alone(14.09.2026 um 18:54 Uhr)
🪟 Windows TippsThe Gemini desktop app is now available for Windows(11.09.2026 um 17:06 Uhr)
🪟 Windows TippsSetting up live captions stuck in Windows 11(14.09.2026 um 16:31 Uhr)
🕵️ SicherheitslückenBurn Out, Or Fade Away(14.09.2026 um 14:25 Uhr)
🪟 Windows TippsWindows 11's latest update broke my speakers, and I'm not alone(14.09.2026 um 18:54 Uhr)

🔧 Programmierung 🕛 vor 3 Monaten 5 Min Lesezeit
0

SQL Window Functions: A Practical Guide to ROW_NUMBER, RANK, LAG, and LEAD

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht

Window functions are one of SQL's most powerful features, but many developers avoid them because the syntax looks unfamiliar. This guide explains when to use them and how to write them correctly.






What is a window function?



A window function performs a calculation across a set of rows related to the current row — without collapsing the rows into a single output row (which is what GROUP BY does).



The key difference:




CODE
-- GROUP BY: one row per group (collapses rows)
SELECT department, AVG(salary) as avg_salary
FROM employees
GROUP BY department;

-- Window function: keeps all rows, adds AVG per department
SELECT name, department, salary,
AVG(salary) OVER (PARTITION BY department) as dept_avg_salary
FROM employees;






With the window function, you can see each employee and the department average on the same row. This is impossible with GROUP BY alone.






The OVER clause



Every window function uses OVER(...) to define the window:




CODE
function_name() OVER (
PARTITION BY column1, column2 -- Optional: groups rows (like GROUP BY)
ORDER BY column3 [ASC|DESC] -- Optional: orders rows within each partition
ROWS/RANGE BETWEEN ... -- Optional: limits the window to a frame
)








  • PARTITION BY: Divides rows into groups. The function resets per group.


  • ORDER BY: Defines row ordering within the window. Required for ranking and lag/lead functions.


  • Frame clause: Limits which rows the window sees (used with aggregate functions).






ROW_NUMBER, RANK, and DENSE_RANK



These three functions assign sequence numbers to rows — useful for pagination, top-N queries, and deduplication.



ROW_NUMBER(): Assigns a unique sequential number. No ties.




CODE
SELECT name, department, salary,
ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) as row_num
FROM employees;






RANK(): Same as ROW_NUMBER but ties get the same rank, and the next rank skips (1, 2, 2, 4 — not 3).



DENSE_RANK(): Ties get the same rank, but no gaps (1, 2, 2, 3 — not 4).



Classic use case — top N per group:




CODE
-- Top 3 earners per department
SELECT * FROM (
SELECT name, department, salary,
ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) as rn
FROM employees
) ranked
WHERE rn <= 3;









LAG and LEAD



LAG looks at the previous row; LEAD looks at the next row. Both require ORDER BY.




CODE
SELECT
date,
revenue,
LAG(revenue, 1) OVER (ORDER BY date) as prev_revenue,
LEAD(revenue, 1) OVER (ORDER BY date) as next_revenue,
revenue - LAG(revenue, 1) OVER (ORDER BY date) as revenue_change
FROM daily_revenue
ORDER BY date;






LAG(column, offset, default):





  • column: the value to look back at


  • offset: how many rows back (default 1)


  • default: value if no previous row exists (default NULL)



Use cases:




  • Calculate day-over-day or month-over-month changes

  • Compare each value to the previous period

  • Find gaps in sequential data






FIRST_VALUE and LAST_VALUE



Returns the first or last value in a window frame.




CODE
SELECT name, department, salary,
FIRST_VALUE(name) OVER (PARTITION BY department ORDER BY salary DESC) as top_earner_in_dept
FROM employees;






Note: LAST_VALUE requires a frame clause to work as expected (the default frame stops at the current row):




CODE
LAST_VALUE(name) OVER (
PARTITION BY department
ORDER BY salary DESC
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
) as lowest_earner_in_dept









SUM and AVG as window functions



Any aggregate function can be used as a window function with OVER():




CODE
-- Running total
SELECT date, revenue,
SUM(revenue) OVER (ORDER BY date) as running_total
FROM daily_revenue;

-- Running total reset per month
SELECT date, revenue,
SUM(revenue) OVER (
PARTITION BY DATE_TRUNC('month', date)
ORDER BY date
) as monthly_running_total
FROM daily_revenue;

-- Moving average (7-day)
SELECT date, revenue,
AVG(revenue) OVER (
ORDER BY date
ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
) as moving_avg_7d
FROM daily_revenue;









NTILE



Divides rows into N approximately equal groups (like percentiles):




CODE
SELECT name, salary,
NTILE(4) OVER (ORDER BY salary) as salary_quartile
FROM employees;
-- salary_quartile = 1 means lowest 25%, 4 means highest 25%









PERCENT_RANK and CUME_DIST



PERCENT_RANK: Returns the relative rank as a value between 0 and 1.




CODE
(rank - 1) / (total rows in partition - 1)






CUME_DIST: Returns the cumulative distribution — the fraction of rows at or below the current row's value.




CODE
SELECT name, salary,
PERCENT_RANK() OVER (ORDER BY salary) as pct_rank,
CUME_DIST() OVER (ORDER BY salary) as cum_dist
FROM employees;









Deduplication with ROW_NUMBER



Window functions are the cleanest way to deduplicate — keep the most recent record per user, per product, etc.:




CODE
-- Keep only the most recent order per customer
WITH ranked AS (
SELECT *,
ROW_NUMBER() OVER (
PARTITION BY customer_id
ORDER BY created_at DESC
) as rn
FROM orders
)
SELECT * FROM ranked WHERE rn = 1;






This is more reliable than DISTINCT ON (PostgreSQL-specific) or correlated subqueries.






Performance considerations



Window functions don't change the number of output rows, but they do sort and scan data:





  • PARTITION BY and ORDER BY cause sorting — index on the ORDER BY column helps

  • Running totals over millions of rows are expensive without an index

  • Some databases (PostgreSQL, SQL Server) compute window functions after WHERE but before ORDER BY — optimise the WHERE clause first






SQL Formatter tip



Window functions can get verbose. A well-formatted query is much easier to audit:




CODE
-- Hard to read
SELECT name,salary,ROW_NUMBER()OVER(PARTITION BY department ORDER BY salary DESC)rn,SUM(salary)OVER(PARTITION BY department)dept_total FROM employees WHERE active=true

-- Properly formatted
SELECT
name,
salary,
ROW_NUMBER() OVER (
PARTITION BY department
ORDER BY salary DESC
) AS rn,
SUM(salary) OVER (
PARTITION BY department
) AS dept_total
FROM employees
WHERE active = true;






A SQL formatter that handles window function syntax keeps complex queries readable. The OVER clause with nested PARTITION BY and ORDER BY is a common place where ad-hoc formatting breaks down.






Window functions unlock patterns that are otherwise impossible in SQL: top-N per group, running totals, period-over-period comparisons, and clean deduplication. Once the OVER clause syntax clicks, they become an indispensable part of analytical SQL.

Vollständiger Original-Bericht
Ausführliche Details, Code-Beispiele & Hersteller-Stellungnahme auf dev.to.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
1 Quelle
The Gemini desktop app is now available for Windows
1 Quelle
Setting up live captions stuck in Windows 11
1 Quelle
Burn Out, Or Fade Away
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten SQL Window Functions: A Practical Guide to ROW_NUMBER, RANK, LAG, and LEAD

Thematisch verwandte Begriffe: Window, Functions, Practical, Guide · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...