Brightlane's pricing analyst wants to compare each product's price to the average price across its category.
Write a query to return the ID, name, category, and price of every product, plus the average price across the product's category on each row.
Assumptions:
- The
productstable has one row per product with anid, aname, acategory_id, and aprice. - A category's average price is the average of
priceacross every product in thatcategory_id. The same value should appear on every row that shares acategory_id.
Output:
- One row per product, with columns
id,name,category_id,price, andcategory_avg_price.
Schema · ecommerce 5 tables
Run previews · Check grades
Write a query, then run it to see results here.
Worked solution Try it yourself first
SELECT
id,
name,
category_id,
price,
AVG(price) OVER (
PARTITION BY
category_id
) AS category_avg_price
FROM
products The shape
AVG(price) OVER (PARTITION BY category_id) computes a separate average for each category_id and writes that category's average onto every row in that category. Rows from category 1 see category 1's average; rows from category 2 see category 2's average. The individual product rows stay intact.
Clause by clause
SELECT id, name, category_id, pricereturns each product's identifier, name, category, and individual price, one row per product.- The window column is:
AVG(price) OVER (PARTITION BY category_id) AS category_avg_pricePARTITION BY category_id splits the row set into one group per distinct category_id. AVG(price) runs inside each group independently, so the value attached to a given product is the average of price across only the rows that share its category_id. Every row in the same category sees the same category_avg_price; rows in different categories see different averages.
FROM productsreads every product. The pricing analyst is comparing each product to its category, so every row stays in.
Why this and not GROUP BY category_id
GROUP BY category_id would collapse the catalog to one row per category, leaving the analyst with the category average but no individual product to compare it to. The job is to show each product's own price alongside its category's average, on the same row. PARTITION BY is the window-function equivalent of GROUP BY that does the grouping without the collapsing.
You practiced AVG(...) OVER (PARTITION BY ...) — compute a per-partition average and replicate the partition value onto every row that shares the partition key.