A window with ORDER BY and no frame clause defaults to everything from the start of the partition to the current row, so SUM gives a running total rather than a partition total.
-- running total, probably not what was wanted
SUM(amount) OVER (PARTITION BY customer_id ORDER BY placed_at)
-- the partition total
SUM(amount) OVER (PARTITION BY customer_id)
-- explicit, and worth writing even when it is the default
SUM(amount) OVER (
PARTITION BY customer_id ORDER BY placed_at
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
)
The rule is that adding ORDER BY to a window changes what the aggregate means, which is not what ordering does anywhere else in SQL. ROWS counts rows and RANGE counts values, so with ties they give different answers — RANGE includes every peer of the current row. Writing the frame out explicitly is three extra words and removes the whole class of misunderstanding for whoever reads the query next.