{"appId":"sql-app","version":1551,"selectedAngularVersion":20,"item":{"id":"lesson-window-functions","conceptKey":"window-functions","subjectId":"subject-window-functions","title":"Window Functions","summary":"Window Functions is a practical SQL concept used to design, query, secure, operate, or analyze relational data correctly.","baseContent":"<h2>Window Functions</h2><p>Window Functions is a practical SQL concept used to design, query, secure, operate, or analyze relational data correctly.</p><h3>Example</h3><pre><code>SELECT id, total, AVG(total) OVER () AS overall_avg FROM orders;</code></pre><h3>Key point</h3><p>Use the smallest correct statement, test it with representative data, and verify constraints and performance before production use.</p><h3>Real-life example</h3><p>A sales manager needs a monthly report showing revenue, order counts, rankings, and changes over time without exporting raw data to a spreadsheet.</p><h3>Advanced example</h3><pre><code>SELECT customer_id, ordered_at, total,\n       SUM(total) OVER (\n         PARTITION BY customer_id\n         ORDER BY ordered_at, id\n         ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW\n       ) AS customer_running_total\nFROM orders;</code></pre><h3>Expected result</h3><p>The query returns only the intended rows and columns, with deterministic ordering where order matters.</p><h3>Production check</h3><ul><li>Test with empty, duplicate, null, and boundary values.</li><li>Use a transaction for related writes.</li><li>Inspect the execution plan before adding an index.</li><li>Use parameterized queries for application input.</li></ul><h3>Continue with the PicoStore database</h3><p>This lesson reuses <strong>picostore</strong>. Relevant tables: <code>customers, products, orders, order_items</code>. Keep the starter rows from the Introduction lesson so results remain comparable.</p><h3>Another practical example</h3><pre><code>SELECT category,\n       COUNT(*) AS products,\n       ROUND(AVG(price), 2) AS average_price,\n       SUM(stock) AS units_available\nFROM products\nGROUP BY category\nHAVING SUM(stock) &gt; 0;</code></pre><h3>Check the result</h3><p>Run the verification query, compare the returned rows with the starter data, and explain why every included or excluded row is correct.</p><section data-sql-reference-catalog=\"true\"><h2>SQL reference catalog: Window Functions</h2><p>This catalog covers the practical public SQL surface. Check the exact server-version documentation before using a vendor-specific item.</p><h3>Ranking functions</h3><ul><li><code>ROW_NUMBER</code> — unique sequence within a window</li><li><code>RANK</code> — rank with gaps after ties</li><li><code>DENSE_RANK</code> — rank without gaps</li><li><code>PERCENT_RANK</code> — relative rank from 0 to 1</li><li><code>CUME_DIST</code> — cumulative distribution</li><li><code>NTILE</code> — divide rows into buckets</li></ul><h3>Navigation/value functions</h3><ul><li><code>LAG</code> — value from a previous row</li><li><code>LEAD</code> — value from a following row</li><li><code>FIRST_VALUE</code> — first value in frame</li><li><code>LAST_VALUE</code> — last value in frame</li><li><code>NTH_VALUE</code> — value at a frame position</li></ul><h3>Aggregates used as windows</h3><ul><li><code>COUNT OVER</code> — running or partition count</li><li><code>SUM OVER</code> — running or partition total</li><li><code>AVG OVER</code> — moving or partition average</li><li><code>MIN OVER / MAX OVER</code> — window extrema</li><li><code>STDDEV / VARIANCE OVER</code> — window statistics</li></ul><h3>Window definition parts</h3><ul><li><code>PARTITION BY</code> — restart calculation by group</li><li><code>ORDER BY</code> — define row sequence</li><li><code>ROWS</code> — physical-row frame</li><li><code>RANGE</code> — peer/value-based frame</li><li><code>GROUPS</code> — peer-group frame; PostgreSQL</li><li><code>EXCLUDE</code> — remove frame rows; PostgreSQL</li></ul></section><section data-nonversioned-curriculum=\"1\"><h3>Easy example</h3><p>Start with a small customer table and retrieve active customers in a predictable order.</p><pre><code>SELECT customer_id, name, email\nFROM customers\nWHERE status = 'active'\nORDER BY name;</code></pre><h3>How to verify the easy example</h3><ul><li>Run it with representative input.</li><li>Confirm the expected output.</li><li>Try one missing, invalid, or boundary value.</li></ul><h3>Advanced example</h3><p>Use a CTE and a window function to rank customer revenue while keeping the query readable and testable.</p><pre><code>WITH customer_revenue AS (\n  SELECT customer_id, SUM(total_amount) AS revenue\n  FROM orders\n  WHERE order_status = 'completed'\n  GROUP BY customer_id\n)\nSELECT customer_id, revenue,\n       DENSE_RANK() OVER (ORDER BY revenue DESC) AS revenue_rank\nFROM customer_revenue\nORDER BY revenue_rank, customer_id;</code></pre><h3>Advanced review</h3><ul><li>Explain the tradeoffs and assumptions.</li><li>Test failure, scale, security, and recovery behavior.</li><li>Capture evidence from tests, execution plans, logs, or review output.</li></ul><h3>Additional practical guidance</h3><div><h3>Window Functions: MySQL and PostgreSQL</h3><p>Prefer standard SQL functions when portability matters. MySQL and PostgreSQL differ most in date formatting, type conversion, string aggregation, and error handling for invalid values.</p><h3>Required verification</h3><ul><li>Run the simple case.</li><li>Test a NULL, duplicate, empty, or boundary case where relevant.</li><li>Confirm the affected rows or query result.</li><li>Use EXPLAIN for performance-sensitive queries.</li></ul></div></section>","detailId":"lesson-window-functions-6785acd9","versions":[],"isActive":true,"detailIsActive":true,"lessonVersions":[],"selectedVersion":20,"content":"","updatedAt":"2026-08-01T09:43:04.474Z","details":[{"id":"lesson-window-functions","conceptKey":"window-functions","subjectId":"subject-window-functions","title":"Window Functions","summary":"Window Functions is a practical SQL concept used to design, query, secure, operate, or analyze relational data correctly.","baseContent":"<h2>Window Functions</h2><p>Window Functions is a practical SQL concept used to design, query, secure, operate, or analyze relational data correctly.</p><h3>Example</h3><pre><code>SELECT id, total, AVG(total) OVER () AS overall_avg FROM orders;</code></pre><h3>Key point</h3><p>Use the smallest correct statement, test it with representative data, and verify constraints and performance before production use.</p><h3>Real-life example</h3><p>A sales manager needs a monthly report showing revenue, order counts, rankings, and changes over time without exporting raw data to a spreadsheet.</p><h3>Advanced example</h3><pre><code>SELECT customer_id, ordered_at, total,\n       SUM(total) OVER (\n         PARTITION BY customer_id\n         ORDER BY ordered_at, id\n         ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW\n       ) AS customer_running_total\nFROM orders;</code></pre><h3>Expected result</h3><p>The query returns only the intended rows and columns, with deterministic ordering where order matters.</p><h3>Production check</h3><ul><li>Test with empty, duplicate, null, and boundary values.</li><li>Use a transaction for related writes.</li><li>Inspect the execution plan before adding an index.</li><li>Use parameterized queries for application input.</li></ul><h3>Continue with the PicoStore database</h3><p>This lesson reuses <strong>picostore</strong>. Relevant tables: <code>customers, products, orders, order_items</code>. Keep the starter rows from the Introduction lesson so results remain comparable.</p><h3>Another practical example</h3><pre><code>SELECT category,\n       COUNT(*) AS products,\n       ROUND(AVG(price), 2) AS average_price,\n       SUM(stock) AS units_available\nFROM products\nGROUP BY category\nHAVING SUM(stock) &gt; 0;</code></pre><h3>Check the result</h3><p>Run the verification query, compare the returned rows with the starter data, and explain why every included or excluded row is correct.</p><section data-sql-reference-catalog=\"true\"><h2>SQL reference catalog: Window Functions</h2><p>This catalog covers the practical public SQL surface. Check the exact server-version documentation before using a vendor-specific item.</p><h3>Ranking functions</h3><ul><li><code>ROW_NUMBER</code> — unique sequence within a window</li><li><code>RANK</code> — rank with gaps after ties</li><li><code>DENSE_RANK</code> — rank without gaps</li><li><code>PERCENT_RANK</code> — relative rank from 0 to 1</li><li><code>CUME_DIST</code> — cumulative distribution</li><li><code>NTILE</code> — divide rows into buckets</li></ul><h3>Navigation/value functions</h3><ul><li><code>LAG</code> — value from a previous row</li><li><code>LEAD</code> — value from a following row</li><li><code>FIRST_VALUE</code> — first value in frame</li><li><code>LAST_VALUE</code> — last value in frame</li><li><code>NTH_VALUE</code> — value at a frame position</li></ul><h3>Aggregates used as windows</h3><ul><li><code>COUNT OVER</code> — running or partition count</li><li><code>SUM OVER</code> — running or partition total</li><li><code>AVG OVER</code> — moving or partition average</li><li><code>MIN OVER / MAX OVER</code> — window extrema</li><li><code>STDDEV / VARIANCE OVER</code> — window statistics</li></ul><h3>Window definition parts</h3><ul><li><code>PARTITION BY</code> — restart calculation by group</li><li><code>ORDER BY</code> — define row sequence</li><li><code>ROWS</code> — physical-row frame</li><li><code>RANGE</code> — peer/value-based frame</li><li><code>GROUPS</code> — peer-group frame; PostgreSQL</li><li><code>EXCLUDE</code> — remove frame rows; PostgreSQL</li></ul></section><section data-nonversioned-curriculum=\"1\"><h3>Easy example</h3><p>Start with a small customer table and retrieve active customers in a predictable order.</p><pre><code>SELECT customer_id, name, email\nFROM customers\nWHERE status = 'active'\nORDER BY name;</code></pre><h3>How to verify the easy example</h3><ul><li>Run it with representative input.</li><li>Confirm the expected output.</li><li>Try one missing, invalid, or boundary value.</li></ul><h3>Advanced example</h3><p>Use a CTE and a window function to rank customer revenue while keeping the query readable and testable.</p><pre><code>WITH customer_revenue AS (\n  SELECT customer_id, SUM(total_amount) AS revenue\n  FROM orders\n  WHERE order_status = 'completed'\n  GROUP BY customer_id\n)\nSELECT customer_id, revenue,\n       DENSE_RANK() OVER (ORDER BY revenue DESC) AS revenue_rank\nFROM customer_revenue\nORDER BY revenue_rank, customer_id;</code></pre><h3>Advanced review</h3><ul><li>Explain the tradeoffs and assumptions.</li><li>Test failure, scale, security, and recovery behavior.</li><li>Capture evidence from tests, execution plans, logs, or review output.</li></ul><h3>Additional practical guidance</h3><div><h3>Window Functions: MySQL and PostgreSQL</h3><p>Prefer standard SQL functions when portability matters. MySQL and PostgreSQL differ most in date formatting, type conversion, string aggregation, and error handling for invalid values.</p><h3>Required verification</h3><ul><li>Run the simple case.</li><li>Test a NULL, duplicate, empty, or boundary case where relevant.</li><li>Confirm the affected rows or query result.</li><li>Use EXPLAIN for performance-sensitive queries.</li></ul></div></section>","detailId":"lesson-window-functions-6785acd9","versions":[],"isActive":true,"detailIsActive":true,"lessonVersions":[],"selectedVersion":20,"content":"","updatedAt":"2026-08-01T09:43:04.474Z"}]}}