Use CasesAIPostgreSQLSQL

How to Automate Weekly Business Reports Straight From Your Database

Every Monday at 9 a.m., someone on your team opens a spreadsheet, logs into the database tool they half-remember how to use, copies a few numbers, pastes the...

Marcus Chen· Solutions EngineerMarch 31, 20269 min read

Every Monday at 9 a.m., someone on your team opens a spreadsheet, logs into the database tool they half-remember how to use, copies a few numbers, pastes them into a slide deck, and emails it to the leadership team. By the time anyone reads it, the data is already a week old. And if that person is sick, on vacation, or just busy the report doesn't happen.

This is not a data problem. It's a workflow problem. Your database already contains everything you need. The issue is that getting it out, formatting it, and delivering it to the right people requires manual steps that nobody should still be doing manually in 2026.

This guide walks through how automated weekly reporting works, what the traditional approaches get wrong, how to set one up yourself with SQL and a scheduler, and how tools like AI for Database cut that setup time from hours to minutes without requiring any automation code.

Why Manual Weekly Reports Break Down

Manual reporting sounds manageable until you actually do it every week. Here's where it tends to fall apart:

It's always stale. A weekly report assembled on Monday morning reflects data through Sunday night and then sits in someone's inbox until Wednesday. Decisions get made on week-old numbers.

It's error-prone. Copy-paste from a query result to a spreadsheet is a human process. Cell references break. Rows get skipped. Formulas drift. The report looks right but isn't.

It creates a single point of failure. When the person who owns the report leaves or is unavailable, the report stops. Nobody else knows the queries, the template, or where the data lives.

It doesn't scale. One weekly report is manageable. Five weekly reports across five departments each with slightly different requirements quickly becomes a part-time job.

The fix is not to make the manual process faster. It's to remove the manual process entirely.

The Traditional Automation Approach (and Why It's Fragile)

The standard engineering approach to automated reporting looks like this: write a script that connects to the database, runs queries, formats the output, and sends an email via cron. Something like this:

# crontab entry to run every Monday at 8am
0 8 * * 1 /usr/bin/python3 /opt/reports/weekly_report.py
import psycopg2
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

conn = psycopg2.connect("postgresql://user:pass@db-host:5432/production")
cur = conn.cursor()

cur.execute("""
    SELECT
        COUNT(*) FILTER (WHERE created_at >= NOW() - INTERVAL '7 days') AS new_signups_7d,
        COUNT(*) FILTER (WHERE created_at >= NOW() - INTERVAL '14 days'
                         AND created_at < NOW() - INTERVAL '7 days') AS new_signups_prev_7d,
        ROUND(
            SUM(mrr) FILTER (WHERE status = 'active'), 2
        ) AS current_mrr
    FROM accounts;
""")

row = cur.fetchone()
new_signups, prev_signups, mrr = row

body = f"""
Weekly Business Report

New Signups (last 7 days): {new_signups}
New Signups (prior 7 days): {prev_signups}
Current MRR: ${mrr:,.2f}
"""

msg = MIMEMultipart()
msg['From'] = 'reports@yourcompany.com'
msg['To'] = 'team@yourcompany.com'
msg['Subject'] = 'Weekly Business Report'
msg.attach(MIMEText(body, 'plain'))

with smtplib.SMTP('smtp.yourhost.com', 587) as server:
    server.starttls()
    server.login('user', 'password')
    server.send_message(msg)

This works. Engineers have been doing it for years. But it has real problems:

  • Maintenance burden. Every schema change a renamed column, a new table can silently break the report or produce wrong numbers.
  • No visibility. If the script fails, you often find out when someone notices the email didn't arrive.
  • Hard to change. A non-technical analyst who wants to add one more metric has to file a ticket and wait.
  • No formatting. A plain-text email with raw numbers is not the same as a readable, scannable report.
  • BI tools like Metabase and Tableau can schedule reports with better formatting but they require standing up infrastructure, maintaining database connections, building dashboards first, and typically need an admin to manage user access and refresh schedules. For small teams, the setup cost often exceeds the benefit.

    What Good Automated Reporting Actually Looks Like

    A well-designed automated weekly report does four things:

  • Runs a defined set of queries on a schedule without anyone pressing a button.
  • Presents results in a readable format not a raw SQL dump, but a structured summary a non-technical reader can act on.
  • Delivers the report to where people actually are email, Slack, a shared dashboard.
  • Stays up to date the dashboard version reflects current data, not a snapshot from last Monday.
  • The reporting layer should be invisible. Your team should see the output without knowing or caring what queries run underneath.

    Setting Up a Weekly Report: Step by Step

    Let's walk through building a weekly business report against a PostgreSQL database. The goal: track new signups, MRR, churned accounts, and top customers by revenue for the past 7 days.

    Step 1: Define Your Core Queries

    Start with the exact metrics you want. Keep it to 5–8 numbers that actually change decisions.

    -- New signups this week vs last week
    SELECT
        COUNT(*) FILTER (WHERE created_at >= NOW() - INTERVAL '7 days') AS signups_this_week,
        COUNT(*) FILTER (WHERE created_at BETWEEN NOW() - INTERVAL '14 days' AND NOW() - INTERVAL '7 days') AS signups_last_week
    FROM users;
    
    -- Current MRR and week-over-week change
    SELECT
        ROUND(SUM(monthly_amount), 2) AS current_mrr,
        ROUND(SUM(monthly_amount) FILTER (
            WHERE subscription_start < NOW() - INTERVAL '7 days'
        ), 2) AS mrr_last_week
    FROM subscriptions
    WHERE status = 'active';
    
    -- Churned accounts this week
    SELECT COUNT(*) AS churned_this_week
    FROM subscriptions
    WHERE status = 'cancelled'
      AND cancelled_at >= NOW() - INTERVAL '7 days';
    
    -- Top 5 customers by MRR
    SELECT
        a.name,
        ROUND(s.monthly_amount, 2) AS mrr
    FROM subscriptions s
    JOIN accounts a ON a.id = s.account_id
    WHERE s.status = 'active'
    ORDER BY s.monthly_amount DESC
    LIMIT 5;

    Step 2: Wrap in a Scheduler

    If you're doing this with code, your cron entry (for a Monday 8am delivery) looks like:

    0 8 * * 1 /usr/bin/python3 /opt/reports/weekly_summary.py >> /var/log/reports/weekly.log 2>&1

    Redirect output to a log file so you can see failures. Add alerting (a simple curl to a Slack webhook on non-zero exit) so you know when the script breaks.

    Step 3: Format for Human Readability

    Raw numbers in a text email are hard to scan. At minimum, add week-over-week change indicators. Better still, generate an HTML email with a simple table. Even better link to a live dashboard that always shows current data.

    Sending Reports via Email, Slack, and Webhooks

    Once the query layer is working, delivery is a configuration problem.

    Email: Use a transactional email service (SendGrid, Postmark, AWS SES) rather than raw SMTP. They handle deliverability, bounce tracking, and provide logs when something goes wrong.

    Slack: Post to a channel using a webhook URL. A weekly report in a #metrics channel that the whole team can see is often more useful than an email that gets buried.

    import requests, json
    
    payload = {
        "text": f"*Weekly Report  {report_date}*\n"
                f"New Signups: {signups} (vs {prev_signups} last week)\n"
                f"MRR: ${mrr:,.0f}\n"
                f"Churned: {churned}"
    }
    
    requests.post(SLACK_WEBHOOK_URL, data=json.dumps(payload))

    Webhooks: If your report needs to trigger downstream actions update a CRM, send to a data warehouse, push to a mobile notification a webhook gives you full flexibility. Build a small endpoint that receives the payload and routes it appropriately.

    Doing This Without Writing Automation Code

    The approach above works, but it assumes you have a developer available to write and maintain the script. For a non-technical founder, a RevOps analyst, or a small team without dedicated engineering resources, that's a real blocker.

    AI for Database is built specifically for this situation. You connect your database PostgreSQL, MySQL, Supabase, BigQuery, MongoDB, MS SQL Server, and others and then interact with it in plain English instead of SQL.

    For weekly reports, the workflow looks like this:

  • Connect your database once (no code required, just connection credentials).
  • Ask a question in natural language: "Show me new signups, MRR, and churn for the past 7 days."
  • The tool generates and runs the SQL, then returns the results in a readable format.
  • Pin the queries to a self-refreshing dashboard that always shows current numbers.
  • Set up an action workflow to deliver the report to your email or Slack channel on a weekly schedule.
  • The self-refreshing dashboard means you don't need to wait for a Monday morning report at all the numbers update automatically. The workflow handles the scheduled delivery without any cron jobs, scripts, or infrastructure to maintain.

    For teams that want a mix developers who also want non-technical teammates to have access AI for Database supports both. Technical users can write raw SQL if they prefer; non-technical users can ask questions in plain language and get the same underlying data.

    Examples of Useful Weekly Reports

    Here are the reports that consistently matter most across different team types:

    SaaS / Subscription Businesses

  • New signups and trial-to-paid conversions this week vs last week
  • Monthly Recurring Revenue (MRR) and week-over-week delta
  • Churned accounts and churned MRR
  • Net Revenue Retention for active cohorts
  • Sales and RevOps

  • New deals created, closed-won, and closed-lost
  • Pipeline value by stage
  • Average deal size and average sales cycle length
  • Top 10 accounts by open opportunity value
  • Product Teams

  • Daily Active Users (DAU) and Weekly Active Users (WAU) over the past 4 weeks
  • Feature adoption: which features were used this week
  • Activation rate: percentage of new signups who completed key onboarding steps
  • Retention by cohort week
  • E-commerce

  • Orders, revenue, and average order value
  • Top products by units sold and revenue
  • Cart abandonment rate
  • Repeat purchase rate
  • Each of these can be expressed as a SQL query against your existing transactional database no data warehouse required. If the data is in your database, you can report on it.

    Ready to try AI for Database?

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