You add a subscriptions table, an events table, a handful of orders. Six months later someone on your team asks "what's our MRR trend?" and three people write three different queries against the raw tables. Each one joins slightly differently, filters test accounts differently (or not at all), and produces a different number. Now there are three "correct" answers in three Slack threads, and nobody trusts the dashboard anymore.

This isn't a tooling problem. It's a workflow problem. Querying raw production tables directly for reporting works fine for one query, one time. It falls apart the moment more than one person needs the same answer, or the same question gets asked twice a week.

The fix is a layered SQL workflow — raw data, cleaned staging views, and business-level marts — that data teams have used for years and that fits perfectly on top of a single Postgres or MySQL database, no data warehouse required. Here's how to build it.

Why querying raw tables directly breaks down

Production tables are shaped for your application, not for reporting. A few concrete problems show up almost immediately: