SQL Kitchen

Lesson · Recipe № 014

Window Functions

Lesson 14
Recipe

Window Functions


GROUP BY collapses rows into one per group. A window function keeps every row, but still lets it look at the rest of its group: OVER (PARTITION BY ...) defines that group, and RANK() gives each row its position within it.

Query

SELECT name, station, price,
       RANK() OVER (PARTITION BY station ORDER BY price DESC) AS price_rank
FROM dishes
ORDER BY station, price_rank;

↓ result

name             station  price  price_rank
Bifteki          grill    18     1
Souvlaki         grill    11     2
Loukoumades      pastry   9      1
Baklava          pastry   7      2
Melitzanosalata  salad    16     1
Dakos            salad    14     2

Leave out PARTITION BY and the window covers every row at once. Combined with SUM() OVER (ORDER BY ...), that gives a running total instead of one grand total.

Window functions can't appear in WHERE directly (they run after filtering), so to keep only the top-ranked row per group, wrap the ranking in a CTE first and filter the outer query on that.

Query

WITH ranked AS (
  SELECT name, station, price,
         ROW_NUMBER() OVER (PARTITION BY station ORDER BY price DESC) AS rn
  FROM dishes
)
SELECT station, name, price
FROM ranked
WHERE rn = 1
ORDER BY station;

↓ result

station  name             price
grill    Bifteki          18
pastry   Loukoumades      9
salad    Melitzanosalata  16

On the rail · tonight's orders

ORDER 040

for Giorgos


Giorgos wants bragging rights settled once and for all: station by station, which dish is the priciest, second priciest, and so on.

Your query returns

Each dish's name, station, price, and its price rank within that station (1 = priciest at that station).


ORDER 041

for Konstantinos


Konstantinos wants a running total of the wine cellar's value, cheapest bottle first, so he knows the cumulative cost as he goes.

Your query returns

Each wine's name, price, and the running total of price so far, cheapest first.


ORDER 042

for Eleni


Eleni's putting together a highlight card for the new menu. She only wants the single priciest dish from each station, nothing else.

Your query returns

One row per station: the name and price of its priciest dish.