Foundations · Data and Tools for Finance

    SQL for Finance Data

    8 min readLast reviewed: July 2025

    Intuition

    Financial databases are large, structured, and relational, multiple tables linked together by common keys (company ID, period, instrument identifier). SQL (Structured Query Language) is the universal language for querying these databases efficiently. Whether you're using Bloomberg's BQUANT, a Prowess database, an internal data warehouse, or a Supabase/PostgreSQL database you've built yourself, SQL is the tool.

    For a finance professional, SQL proficiency means the ability to slice, aggregate, filter, and join financial data at scale, extracting exactly the numbers you need rather than downloading everything and filtering in Excel. It also means you can write queries that others can read, understand, and audit, creating reproducible analysis.

    SQL is not a programming language per se, it's a declarative query language. You describe what data you want; the database engine figures out how to fetch it. The learning curve is gentler than Python, making it one of the highest ROI skills for a financial analyst.

    Mechanics

    Core SQL for financial analysis:

    SELECT and filtering:

    SELECT company_name, revenue, ebitda_margin, fy
    FROM financials
    WHERE sector = 'Pharmaceuticals'
      AND fy BETWEEN 2020 AND 2025
      AND revenue > 5000  -- ₹ Crore
    ORDER BY revenue DESC;
    

    Aggregations:

    SELECT sector,
           AVG(ebitda_margin) AS avg_margin,
           COUNT(*) AS company_count
    FROM financials
    WHERE fy = 2024
    GROUP BY sector
    HAVING COUNT(*) >= 5
    ORDER BY avg_margin DESC;
    

    JOINs (linking tables):

    SELECT c.company_name, f.revenue, f.pat, p.pe_ratio
    FROM companies c
    JOIN financials f ON c.id = f.company_id AND f.fy = 2024
    JOIN price_multiples p ON c.id = p.company_id;
    

    Window functions (YoY growth, running totals):

    SELECT company_name, fy, revenue,
           revenue / LAG(revenue) OVER (PARTITION BY company_id ORDER BY fy) - 1
             AS revenue_growth_yoy
    FROM financials
    ORDER BY company_id, fy;
    

    CTEs (Common Table Expressions) for readable multi-step queries:

    WITH sector_avg AS (
      SELECT sector, AVG(roe) AS avg_roe FROM financials WHERE fy=2024 GROUP BY sector
    )
    SELECT f.company_name, f.roe, s.avg_roe,
           f.roe - s.avg_roe AS roe_premium
    FROM financials f
    JOIN sector_avg s ON f.sector = s.sector
    WHERE f.fy = 2024;
    

    Try it yourself

    Interactive exercises coming soon.

    Related topics

    Stay in the loop

    Roughly one email per month. No spam, no upsells.