Brightlane's operations team is preparing an order status summary for the weekly review.
Write a query to return the total number of orders, the number of delivered orders, and the number of pending orders as a single row.
Assumptions:
- The
orderstable has one row per order with astatus. - The total count covers every order. The delivered count covers only orders with
status = 'delivered'. The pending count covers only orders withstatus = 'pending'.
Output:
- A single row with columns
total_orders,delivered_orders, andpending_orders.
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
COUNT(*) AS total_orders,
COUNT(*) FILTER (
WHERE
status = 'delivered'
) AS delivered_orders,
COUNT(*) FILTER (
WHERE
status = 'pending'
) AS pending_orders
FROM
orders The shape
Three counts over the same orders table, each restricted to a different rule. COUNT(*) with no filter counts every order; the two COUNT(*) FILTER (...) expressions each count only the orders matching their own condition. One pass over the table, three independent counts.
Clause by clause
SELECT COUNT(*) AS total_orderscounts every row inorders. No condition attached, so every order contributes one.COUNT(*) FILTER (WHERE status = 'delivered') AS delivered_orderscounts only the orders whosestatusis'delivered'. TheFILTERclause sits next to the aggregate it constrains; rows where the condition is false are excluded from this count and this count only.COUNT(*) FILTER (WHERE status = 'pending') AS pending_ordersdoes the same for orders whosestatusis'pending'. Pending and delivered are independent filters; an order excluded by one stays visible to the other and to the unfiltered count.FROM ordersreads the order records. NoGROUP BYbecause the prompt asks for a single summary row, and aggregate functions withoutGROUP BYcollapse the whole table into one row.
Why this and not COUNT(CASE WHEN status = 'delivered' THEN 1 END)
The CASE WHEN form produces the same numbers. FILTER is easier to scan when several conditional counts sit side by side in one SELECT list, because each condition reads on its own line right next to the aggregate it constrains. For three parallel counts like the ones the weekly review needs, FILTER keeps each one self-contained instead of nesting a per-row decision inside each function.
You practiced COUNT(*) FILTER (WHERE ...) for parallel conditional counts — three counts over the same record set, each restricted to its own condition, in a single pass.