Brightlane's operations director is reviewing the active order pipeline and wants to exclude orders that have already reached a terminal state.
Write a query to return the ID, status, and total amount for every order that is neither delivered nor cancelled.
Assumptions:
- The
orderstable contains every order Brightlane has ever recorded. - Terminal states are
deliveredandcancelled; every other value ofstatusrepresents an order still in the active pipeline.
Output:
- One row per non-terminal order, with columns
id,status, andtotal_amount.
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,
status,
total_amount
FROM
orders
WHERE
NOT (
status = 'delivered'
OR status = 'cancelled'
) The shape
NOT applied to an OR group. The inner expression collects every terminal state, and NOT flips it so the query keeps everything else. The active pipeline is whatever isn't yet finished.
Clause by clause
SELECT id, status, total_amountreturns the order, its state, and its dollar amount. Includingstatusin the output makes the filter easy to audit; every row shows the state that earned its inclusion.FROM ordersreads every order Brightlane has ever recorded.WHERE NOT (status = 'delivered' OR status = 'cancelled')is the exclusion. The innerORis true whenever the order has reached a terminal state.NOTflips that result, so the rows that pass are the ones where the inner expression was false: orders still in flight (pending,shipped, and so on).
Why the parentheses around the OR
Without them, the query reads NOT status = 'delivered' OR status = 'cancelled'. NOT binds tighter than OR, so PostgreSQL groups it as (NOT status = 'delivered') OR (status = 'cancelled'). That keeps every non-delivered order, including cancelled ones, plus every cancelled order a second time. The opposite of the intent.
The parentheses make NOT apply to the whole OR expression as a single unit. That produces the exclusion semantics: "none of these terminal states."
The trap
NOT with an OR group looks symmetric, so the parens feel cosmetic. They aren't. NOT binds tighter than OR, so dropping them shifts which subexpression NOT applies to, and the query returns a different set of rows. Operations dashboards that should exclude two states end up including one of them twice, and the count looks roughly right at a glance. Any time NOT precedes a compound condition, wrap the whole inner expression in parentheses so NOT covers all of it.
You practiced using NOT to invert a compound condition — NOT (status = 'delivered' OR status = 'cancelled') keeps every row whose status is none of the listed terminal states. Inverting an OR-of-equalities is the canonical shape of an exclusion filter.