None of these will throw an error. That's what makes them dangerous. The query runs, returns a number, and the number is wrong.
Mistake | What it looks like | Why it's wrong | The fix |
|---|---|---|---|
Fan-out from a join | Joining orders to a table with multiple rows per order (like order_items) before summing revenue | Revenue gets counted once per item, inflating the total | Aggregate the items table first, or join after aggregating |
Wrong join type | Using INNER JOIN when you needed LEFT JOIN | Silently drops rows with no match, as in Lesson 2.4 | Ask "should rows with no match still appear, as zero" before choosing the join |
Timezone mismatch | Comparing a UTC timestamp to a "today" defined in your local timezone | Off-by-one-day errors, especially near midnight | Confirm what timezone your data is stored in before filtering on dates |
Counting rows instead of distinct users | COUNT(*) on an events table when you meant "how many unique people" | One highly active user can make the number look far bigger than it is | Use COUNT(DISTINCT user_id) when the question is about people, not events |
Filtering after aggregating, incorrectly | Trying to use WHERE to filter on the result of a COUNT or SUM | WHERE runs before grouping happens, so it can't see aggregate results, and will error or behave unexpectedly | Use HAVING instead of WHERE when filtering on an aggregated value |
Survivorship bias in the table itself | Querying a subscriptions table that only contains currently active subscriptions | You'll undercount churn, because cancelled subscriptions may have been deleted, not flagged | Confirm whether the table represents current state or full history before trusting any denominator |
That last row deserves its own sentence, because it's the most product-relevant one on this list: know whether the table you're querying holds current state or full history, before you trust any count that depends on things that used to exist but don't anymore. This is exactly the training-data-style lesson of "what does this label actually mean, and who decided" applied to a live production table.
YOUR MOVE THIS WEEK
Pick one metric your team reports regularly. Ask the person who built the underlying query: which of these six mistakes did you specifically design around? If they can't answer confidently, that's not necessarily a wrong number today, but it's an unverified one, and it's worth a follow-up.