Use CasesAIPostgreSQLSQL

Database Reporting for Finance Teams: Live Numbers Without the IT Queue

Finance teams are in a peculiar situation. They're the most data-dependent people in the company responsible for revenue recognition, cash flow forecasting,...

Priya Sharma· Product LeadMarch 30, 20268 min read

Finance teams are in a peculiar situation. They're the most data-dependent people in the company responsible for revenue recognition, cash flow forecasting, expense tracking, and board reporting yet they're almost always last in the queue when they need a new report from engineering.

The irony is that the data they need is already in the company's databases. Subscription billing, transaction records, expense categories, payroll data, invoice statuses all of it is queryable. The bottleneck isn't the data; it's access.

This article covers the most valuable queries finance teams can run against their databases, how to build reports that refresh automatically, and how to get meaningful numbers without needing SQL expertise or a data analyst on call.

Why Finance Data Lives in Your Database, Not Just Your Accounting Software

Accounting platforms like QuickBooks, Xero, and NetSuite are designed for bookkeeping. They're authoritative for what's been invoiced and paid. But they're deliberately backward-looking and limited in what they can compute on the fly.

The raw transactional data that feeds those platforms or that exists independently in your product database is often far richer:

  • Billing system tables: Every subscription, plan change, payment, refund, and credit
  • Product activity tables: Which customers are actually using what they're paying for
  • Contract/CRM tables: Deal terms, renewal dates, discount rates
  • Support/usage tables: Signals that predict churn before accounting sees it
  • When you can query these directly, you can answer questions that your accounting software simply can't: "What's our net revenue retention this quarter?" or "Which enterprise customers are at risk of non-renewal based on usage data?"

    The Core Financial Queries

    These queries target common finance reporting needs. They're written in standard SQL (PostgreSQL-style) adapt field names to your schema.

    Monthly Recurring Revenue (MRR)

    SELECT
      DATE_TRUNC('month', s.started_at) AS month,
      SUM(
        CASE
          WHEN s.billing_interval = 'month' THEN s.amount
          WHEN s.billing_interval = 'year' THEN s.amount / 12
          ELSE 0
        END
      ) AS mrr
    FROM subscriptions s
    WHERE s.status = 'active'
      AND s.started_at >= '2025-01-01'
    GROUP BY DATE_TRUNC('month', s.started_at)
    ORDER BY month;

    Most SaaS teams track this manually in a spreadsheet. Running it directly from your subscriptions table means you get the number as of now, not as of whenever someone last updated the sheet.

    MRR Movement (New, Expansion, Contraction, Churn)

    WITH mrr_by_customer AS (
      SELECT
        customer_id,
        DATE_TRUNC('month', period_start) AS month,
        SUM(amount) AS mrr
      FROM subscription_line_items
      WHERE status = 'active'
      GROUP BY customer_id, DATE_TRUNC('month', period_start)
    ),
    mrr_changes AS (
      SELECT
        curr.month,
        curr.customer_id,
        COALESCE(curr.mrr, 0) AS current_mrr,
        COALESCE(prev.mrr, 0) AS previous_mrr,
        COALESCE(curr.mrr, 0) - COALESCE(prev.mrr, 0) AS change
      FROM mrr_by_customer curr
      LEFT JOIN mrr_by_customer prev
        ON prev.customer_id = curr.customer_id
        AND prev.month = curr.month - INTERVAL '1 month'
    )
    SELECT
      month,
      SUM(CASE WHEN previous_mrr = 0 AND current_mrr > 0 THEN current_mrr ELSE 0 END) AS new_mrr,
      SUM(CASE WHEN change > 0 AND previous_mrr > 0 THEN change ELSE 0 END) AS expansion_mrr,
      SUM(CASE WHEN change < 0 AND current_mrr > 0 THEN ABS(change) ELSE 0 END) AS contraction_mrr,
      SUM(CASE WHEN current_mrr = 0 AND previous_mrr > 0 THEN previous_mrr ELSE 0 END) AS churned_mrr
    FROM mrr_changes
    GROUP BY month
    ORDER BY month;

    This is the waterfall view every SaaS CFO needs. Running it from the database means it's always current, not dependent on someone remembering to update it.

    Outstanding Invoice Aging

    SELECT
      customer_name,
      invoice_number,
      amount_due,
      due_date,
      CURRENT_DATE - due_date AS days_overdue
    FROM invoices
    WHERE status IN ('unpaid', 'partial')
      AND due_date < CURRENT_DATE
    ORDER BY days_overdue DESC;

    A simple query, but the difference between running this once a week from a live database versus exporting a CSV from your billing tool every time is hours of manual work per month.

    Net Revenue Retention (NRR)

    WITH cohort_mrr AS (
      SELECT
        s.customer_id,
        DATE_TRUNC('month', s.started_at) AS cohort_month,
        SUM(s.amount) AS starting_mrr
      FROM subscriptions s
      WHERE DATE_TRUNC('month', s.started_at) = '2025-01-01'
      GROUP BY s.customer_id, DATE_TRUNC('month', s.started_at)
    ),
    current_mrr AS (
      SELECT
        s.customer_id,
        SUM(s.amount) AS current_mrr
      FROM subscriptions s
      WHERE s.status = 'active'
        AND DATE_TRUNC('month', CURRENT_DATE) = '2026-01-01'
      GROUP BY s.customer_id
    )
    SELECT
      ROUND(
        SUM(COALESCE(c.current_mrr, 0)) / SUM(cohort.starting_mrr) * 100, 1
      ) AS nrr_pct
    FROM cohort_mrr cohort
    LEFT JOIN current_mrr c ON c.customer_id = cohort.customer_id;

    NRR above 100% means expansion revenue exceeds churn the hallmark of a healthy SaaS business. This number should be in your board slides every quarter, and it should come directly from your database, not from a spreadsheet approximation.

    Building Self-Updating Finance Reports

    The problem with SQL queries is they require someone to run them. Finance teams typically deal with this in one of three ways:

  • Ask an engineer slow, creates dependency, takes engineers away from product work
  • Export to spreadsheet manual, error-prone, immediately outdated
  • Use a BI tool requires pre-built dashboards, inflexible for ad-hoc questions
  • There's a fourth option: connect your database to a tool that lets non-technical team members ask questions directly, and build dashboards that refresh on a schedule.

    With AI for Database, a CFO or controller can type:

    "Show me MRR by month for the last 12 months"

    or

    "Which customers have invoices more than 60 days overdue?"

    The tool generates the SQL, runs it against your database, and returns the result as a table or chart. You can then pin that question to a finance dashboard that refreshes every morning no engineer involvement after the initial database connection.

    Automating Financial Alerts

    Beyond dashboards, finance teams benefit enormously from proactive alerts. Not "check the dashboard" but "the dashboard noticed something and told you."

    Useful financial alerts to set up:

    Cash flow early warning: Alert when total outstanding receivables exceed your target threshold, or when a single customer's overdue balance crosses a threshold that matters.

    MRR drop detection: If monthly recurring revenue contracts more than a set percentage week-over-week, that's an early warning before the end-of-quarter scramble.

    Large refund or credit: Alert finance whenever a transaction reversal above a certain amount is recorded useful for fraud detection and for staying on top of exceptions before they become surprises.

    Subscription renewal pipeline: Weekly digest of upcoming renewals in the next 30 days with their ARR value so account management knows where to focus.

    These alerts don't require DBA access or stored procedures. You define the condition in plain language, connect it to email or Slack, and the system monitors it on your schedule. The alert fires when the condition is true you don't need to check.

    Common Finance Reporting Scenarios

    Board and Investor Reporting

    Board decks typically need: MRR, ARR, YoY growth, gross margin, burn rate, and runway. The first three come from your billing database. If your expense data is also in a queryable form (even a structured CSV in a database table), you can compute gross margin and burn from the same place.

    The advantage over spreadsheets: when the board asks "what's this number based on?", you can show them the query. The methodology is transparent and reproducible.

    Revenue Recognition Scheduling

    For SaaS businesses with annual contracts, revenue recognition means spreading recognized revenue over the contract period. A query like this helps:

    SELECT
      customer_name,
      contract_start,
      contract_end,
      total_contract_value,
      total_contract_value /
        (DATE_PART('month', AGE(contract_end, contract_start)) + 1) AS monthly_recognized_revenue
    FROM contracts
    WHERE status = 'active'
    ORDER BY monthly_recognized_revenue DESC;

    Running this directly means you're always working with current contract data, not a spreadsheet that hasn't been updated since last month's close.

    Expense Category Tracking

    If your expense management system exports to a database (many do), you can query it with the same approach:

    SELECT
      category,
      SUM(amount) AS total_spend,
      COUNT(*) AS transaction_count
    FROM expenses
    WHERE expense_date >= DATE_TRUNC('month', CURRENT_DATE)
    GROUP BY category
    ORDER BY total_spend DESC;

    This gives you current-month spend by category without waiting for a system-generated report.

    Getting Finance Teams Access Without Security Risk

    A common objection: "We can't give the finance team direct database access what if they accidentally modify something?"

    This is a valid concern, but read-only access solves it. Most databases support read-only database users who can SELECT but not INSERT, UPDATE, or DELETE. Create a dedicated read-only credential for finance reporting, and connect that to AI for Database or whatever query tool you use.

    Additionally, you can restrict which schemas and tables are visible. Finance doesn't need access to your raw user authentication tables or internal system logs just the billing, subscription, and financial tables. Schema-level permissions let you be precise about what's accessible.

    The result: your finance team gets self-serve data access. Engineers stop fielding "can you pull this for me?" requests. And there's no risk of accidental data modification because the credentials don't allow it.

    The Practical Path Forward

    The goal isn't to replace your accounting system it's to give your finance team direct access to the transactional data that feeds it, so they can answer questions faster, build reports that stay current, and stop depending on engineers for every data pull.

    The starting point:

  • Identify which database holds your most important financial data (usually your billing or product database)
  • Create a read-only database user with access to the relevant schemas
  • Connect it to AI for Database or a similar tool
  • Build three core reports: MRR over time, AR aging, and revenue by customer segment
  • Set those reports to auto-refresh on your review cycle (daily for AR, weekly for MRR)
  • From there, add alerts for the exceptions that matter most overdue invoices, unusual churn, unexpected refunds.

    Your database already has the data. The bottleneck is just access. AI for Database gives finance teams that access in plain English, with dashboards that refresh automatically and alerts that surface problems before they reach the board deck.

    Ready to try AI for Database?

    Query your database in plain English. No SQL required. Start free today.