Interview question
Return paid order totals for active customers
Writes a left-join aggregate that keeps active customers with no paid orders and applies date filters without changing join semantics.
TL;DR
Writes a left-join aggregate that keeps active customers with no paid orders and applies date filters without changing join semantics.
LEFT JOIN semantics, aggregate correctness, half-open date ranges, null totals, and business-shaped results.
Practice the problem like a real interview: restate, reason, implement, and test.
Tables: Customers(CustomerId, Name, IsActive) and Orders(OrderId, CustomerId, Status, PaidAt, TotalAmount). Return CustomerId, Name, PaidOrderCount, and PaidTotal for [FromUtc, ToUtc). Every active customer must appear even when no matching paid order exists.
Ada has two paid orders worth 40 and 60 in the period, so her row contains count 2 and total 100. Lin is active but has no paid order in the period, so Lin still appears with count 0 and total 0.
@FromUtc inclusive and @ToUtc exclusive.Status = 'Paid' contributes to the count and total.WHERE.I start from Customers because that is the set the result promises to preserve. Conditions that decide whether an order contributes belong in the join predicate. I then group by the customer columns and convert the null sum produced by no matches to zero. COUNT(o.OrderId) returns zero for an unmatched customer because the joined order id is null.
SELECT
c.CustomerId,
c.Name,
COUNT_BIG(o.OrderId) AS PaidOrderCount,
COALESCE(SUM(o.TotalAmount), CONVERT(decimal(18, 2), 0)) AS PaidTotal
FROM dbo.Customers AS c
LEFT JOIN dbo.Orders AS o
ON o.CustomerId = c.CustomerId
AND o.Status = 'Paid'
AND o.PaidAt >= @FromUtc
AND o.PaidAt < @ToUtc
WHERE c.IsActive = 1
GROUP BY c.CustomerId, c.Name
ORDER BY c.CustomerId;
The database can seek matching order rows efficiently with an index beginning with CustomerId and then the filtering columns, or with a suitable filtered index for paid orders. The grouping work grows with the matching order rows, while the customer scan determines how many zero-total rows must still be returned.
@FromUtc and @ToUtc.TotalAmount if the schema permits it.o.Status or o.PaidAt in WHERE and removing zero-order customers.COUNT(*), which returns one for the null-extended row.Next in Query Practice: Users Without Orders