Financial Analytics Database

Complete Database Schema & Analytical SQL Queries

Database Overview

This database, financial_analytics, is designed for comprehensive financial data analysis including company information, stock prices, and financial statements with calculated ratios.

The schema consists of 3 main tables that support various analytical queries for fundamental analysis, sector comparison, and market valuation.

Interactive Features: Click "Run Query" to view CSV results from the database. All results are pre-generated and stored in the query_data folder.

DATABASE SCHEMA

Database: financial_analytics

The database contains three core tables that form the foundation for financial analysis:

  1. companies - Company metadata and information
  2. stock_prices - Daily historical stock prices
  3. financial_statements - Financial statements with calculated ratios

1. Table: companies

Stores company metadata including name, sector, industry, and other descriptive information.

Column Name Data Type Description
ticker VARCHAR(10) Primary key, stock ticker symbol
name VARCHAR(255) Company name
sector VARCHAR(100) Business sector (e.g., Technology, Healthcare)
industry VARCHAR(100) Specific industry classification
country VARCHAR(100) Country of headquarters
website VARCHAR(255) Company website URL
description TEXT Company description/business overview
currency VARCHAR(10) Reporting currency
last_updated TIMESTAMP Updated timestamp

2. Table: stock_prices

Contains daily historical stock price data including OHLC (Open, High, Low, Close) prices and volume.

Column Name Data Type Description
id INT Auto-increment primary key
ticker VARCHAR(10) Foreign key to companies table
date DATE Trading date
open DECIMAL(15,4) Opening price
high DECIMAL(15,4) Daily high price
low DECIMAL(15,4) Daily low price
close DECIMAL(15,4) Closing price
adj_close DECIMAL(15,4) Adjusted closing price
volume BIGINT Trading volume

3. Table: financial_statements

Comprehensive financial statement data including income statement, balance sheet items, and pre-calculated financial ratios.

Column Name Data Type Description
id INT Auto-increment primary key
ticker VARCHAR(10) Foreign key to companies table
report_date DATE Financial report date
period VARCHAR(20) Reporting period ('12M', 'TTM', '3M')
revenue DECIMAL(20,2) Total revenue/sales
cogs DECIMAL(20,2) Cost of goods sold
gross_profit DECIMAL(20,2) Revenue minus COGS
opex DECIMAL(20,2) Operating expenses
operating_income_ebit DECIMAL(20,2) Operating income/EBIT
ebt DECIMAL(20,2) Earnings before tax
net_income DECIMAL(20,2) Net income/profit
ebitda DECIMAL(20,2) Earnings before interest, tax, depreciation & amortization
... Plus 30+ additional columns for balance sheet items and financial ratios

Note: This table includes comprehensive financial data with columns for income statement, balance sheet (assets, liabilities, equity), and pre-calculated financial ratios (profitability, liquidity, solvency, efficiency ratios).

Complete Schema SQL

The complete database schema creation script:

Click to Show/Hide SQL Code
-- backend/sql/schema.sql
-- Project: Global Market Insight 360
-- Author: Hoang Son Lai

CREATE DATABASE IF NOT EXISTS financial_analytics;
USE financial_analytics;

-- 1. Table: Company Information
CREATE TABLE IF NOT EXISTS companies (
    ticker VARCHAR(10) PRIMARY KEY,
    name VARCHAR(255),
    sector VARCHAR(100),
    industry VARCHAR(100),
    country VARCHAR(100),
    website VARCHAR(255),
    description TEXT,
    currency VARCHAR(10),
    last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

-- 2. Table: Stock Prices (Daily)
CREATE TABLE IF NOT EXISTS stock_prices (
    id INT AUTO_INCREMENT PRIMARY KEY,
    ticker VARCHAR(10),
    date DATE,
    open DECIMAL(15, 4),
    high DECIMAL(15, 4),
    low DECIMAL(15, 4),
    close DECIMAL(15, 4),
    adj_close DECIMAL(15, 4),
    volume BIGINT,
    FOREIGN KEY (ticker) REFERENCES companies(ticker) ON DELETE CASCADE,
    UNIQUE KEY unique_stock (ticker, date)
);

-- 3. Table: Financial Statements (Yearly/Quarterly) & Calculated Ratios
CREATE TABLE IF NOT EXISTS financial_statements (
    id INT AUTO_INCREMENT PRIMARY KEY,
    ticker VARCHAR(10),
    report_date DATE,
    period VARCHAR(20), -- '12M' for Yearly, 'TTM' or '3M'

    -- Income Statement
    revenue DECIMAL(20, 2),
    cogs DECIMAL(20, 2),
    gross_profit DECIMAL(20, 2),
    opex DECIMAL(20, 2),
    operating_income_ebit DECIMAL(20, 2),
    ebt DECIMAL(20, 2),
    net_income DECIMAL(20, 2),
    ebitda DECIMAL(20, 2),
    basic_eps DECIMAL(10, 4),
    diluted_eps DECIMAL(10, 4),

    -- Balance Sheet
    total_assets DECIMAL(20, 2),
    current_assets DECIMAL(20, 2),
    cash_and_equivalents DECIMAL(20, 2),
    accounts_receivable DECIMAL(20, 2),
    inventory DECIMAL(20, 2),
    non_current_assets DECIMAL(20, 2),
    total_liabilities DECIMAL(20, 2),
    current_liabilities DECIMAL(20, 2),
    accounts_payable DECIMAL(20, 2),
    short_term_debt DECIMAL(20, 2),
    long_term_debt DECIMAL(20, 2),
    total_equity DECIMAL(20, 2),
    common_stock DECIMAL(20, 2),
    retained_earnings DECIMAL(20, 2),

    -- Calculated Ratios
    current_ratio DECIMAL(10, 4),
    quick_ratio DECIMAL(10, 4),
    cash_ratio DECIMAL(10, 4),
    debt_to_equity DECIMAL(10, 4),
    debt_ratio DECIMAL(10, 4),
    interest_coverage_ratio DECIMAL(10, 4),
    roa DECIMAL(10, 4),
    roe DECIMAL(10, 4),
    gross_margin DECIMAL(10, 4),
    net_margin DECIMAL(10, 4),
    asset_turnover DECIMAL(10, 4),
    inventory_turnover DECIMAL(10, 4),
    receivables_turnover DECIMAL(10, 4),

    FOREIGN KEY (ticker) REFERENCES companies(ticker) ON DELETE CASCADE,
    UNIQUE KEY unique_financial (ticker, report_date)
);

ANALYTICAL SQL QUERIES

Query Categories

The following analytical queries leverage the database schema to provide insights into company performance, sector comparisons, and market valuation.

All query results are pre-generated and stored as CSV files. Click "Run Query" to view results.

SECTION 1: FUNDAMENTAL ANALYSIS

1. Top 10 Companies by Revenue (Most Recent Year)

This query identifies the top 10 companies based on revenue using their most recent financial year data.

Key metrics displayed:

  • Company name and sector
  • Report date (most recent fiscal year)
  • Revenue and net income (formatted with thousand separators)

Note: Only the latest financial statement for each company is considered.

SQL Query 1
-- 1. Top 10 Companies by Revenue (Most Recent Year)
WITH LatestFinancials AS (
    SELECT 
        f1.*,
        ROW_NUMBER() OVER (PARTITION BY f1.ticker ORDER BY f1.report_date DESC) as rn
    FROM financial_statements f1
    WHERE f1.revenue IS NOT NULL AND f1.revenue > 0
)
SELECT 
    c.name, 
    c.sector, 
    f.report_date, 
    FORMAT(f.revenue, 0) as revenue, 
    FORMAT(f.net_income, 0) as net_income
FROM LatestFinancials f
JOIN companies c ON f.ticker = c.ticker
WHERE f.rn = 1
ORDER BY f.revenue DESC
LIMIT 10;

Query 1 Results: Top 10 Companies by Revenue (Most Recent Year)

2. Profitability Leaders: Highest Net Profit Margin (Most Recent Year)

Identifies companies with the highest net profit margin using their most recent financial year data.

Formula: (Net Income / Revenue) × 100

Includes both net margin and gross margin percentages for comprehensive analysis.

Note: Only the latest financial statement for each company is considered.

SQL Query 2
-- 2. Profitability Leaders: Highest Net Profit Margin (Most Recent Year)
WITH LatestFinancials AS (
    SELECT 
        f1.*,
        ROW_NUMBER() OVER (PARTITION BY f1.ticker ORDER BY f1.report_date DESC) as rn
    FROM financial_statements f1
    WHERE f1.revenue > 0
)
SELECT 
    c.ticker, 
    c.name, 
    f.report_date,
    ROUND(f.net_margin * 100, 2) as net_margin_percent,
    ROUND(f.gross_margin * 100, 2) as gross_margin_percent
FROM LatestFinancials f
JOIN companies c ON f.ticker = c.ticker
WHERE f.rn = 1
ORDER BY f.net_margin DESC
LIMIT 10;

Query 2 Results: Highest Net Profit Margin (Most Recent Year)

3. Financial Health: Companies with High Debt Risk (Debt-to-Equity > 2) - Most Recent Year

Highlights companies with potentially risky debt levels (Debt-to-Equity ratio > 2) using their most recent financial data.

Also shows current ratio and interest coverage ratio for further analysis of financial health.

Note: Only the latest financial statement for each company is considered.

SQL Query 3
-- 3. Financial Health: Companies with High Debt Risk (Most Recent Year)
WITH LatestFinancials AS (
    SELECT 
        f1.*,
        ROW_NUMBER() OVER (PARTITION BY f1.ticker ORDER BY f1.report_date DESC) as rn
    FROM financial_statements f1
    WHERE f1.debt_to_equity IS NOT NULL
)
SELECT 
    c.name, 
    c.industry, 
    f.debt_to_equity,
    f.current_ratio,
    f.interest_coverage_ratio,
    f.report_date
FROM LatestFinancials f
JOIN companies c ON f.ticker = c.ticker
WHERE f.rn = 1 AND f.debt_to_equity > 2
ORDER BY f.debt_to_equity DESC;

Query 3 Results: High Debt Risk Companies (Most Recent Year)

4. Efficient Operations: Best Return on Equity (ROE) & ROA (Most Recent Year)

Ranks companies by Return on Equity (ROE) using their most recent financial year data, showing the top 10 performers.

Also includes Return on Assets (ROA) for comparison of asset utilization efficiency.

Note: Only the latest financial statement for each company is considered.

SQL Query 4
-- 4. Efficient Operations: Best Return on Equity (ROE) & ROA (Most Recent Year)
WITH LatestFinancials AS (
    SELECT 
        f1.*,
        ROW_NUMBER() OVER (PARTITION BY f1.ticker ORDER BY f1.report_date DESC) as rn
    FROM financial_statements f1
    WHERE f1.roe IS NOT NULL
)
SELECT 
    c.ticker,
    c.name,
    f.report_date,
    ROUND(f.roe * 100, 2) as roe_percent,
    ROUND(f.roa * 100, 2) as roa_percent
FROM LatestFinancials f
JOIN companies c ON f.ticker = c.ticker
WHERE f.rn = 1
ORDER BY f.roe DESC
LIMIT 10;

Query 4 Results: Best ROE & ROA (Most Recent Year)

SECTION 2: SECTOR ANALYSIS

5. Average Profit Margin by Sector (Most Recent Year)

Aggregates financial metrics at the sector level using the most recent financial year data for each company.

Shows average net margin and ROE for each sector, along with the number of companies and the latest report date.

Note: Only the latest financial statement for each company is considered for accurate sector comparisons.

SQL Query 5
-- 5. Average Profit Margin by Sector (Most Recent Year)
WITH LatestFinancials AS (
    SELECT 
        f1.*,
        ROW_NUMBER() OVER (PARTITION BY f1.ticker ORDER BY f1.report_date DESC) as rn
    FROM financial_statements f1
    WHERE f1.revenue > 0
),
LatestCompanyData AS (
    SELECT 
        c.sector,
        f.ticker,
        f.net_margin,
        f.roe,
        f.report_date
    FROM LatestFinancials f
    JOIN companies c ON f.ticker = c.ticker
    WHERE f.rn = 1
)
SELECT 
    sector,
    COUNT(DISTINCT ticker) as company_count,
    ROUND(AVG(net_margin) * 100, 2) as avg_net_margin_percent,
    ROUND(AVG(roe) * 100, 2) as avg_roe_percent,
    MAX(report_date) as latest_report_date
FROM LatestCompanyData
GROUP BY sector
ORDER BY avg_net_margin_percent DESC;

Query 5 Results: Average Profit Margin by Sector (Most Recent Year)

SECTION 3: MARKET ANALYSIS & VALUATION

6. Calculate P/E Ratio (Price-to-Earnings) manually

Calculates P/E ratio by joining the most recent stock price with the most recent earnings per share (EPS).

Uses Common Table Expressions (CTEs) to get latest price and EPS data before joining them.

SQL Query 6
-- 6. Calculate P/E Ratio (Price-to-Earnings) manually
WITH LatestPrice AS (
    -- Get the most recent closing price for each ticker
    SELECT ticker, close as latest_price, date
    FROM stock_prices
    WHERE date = (SELECT MAX(date) FROM stock_prices)
),
LatestEPS AS (
    -- Get the most recent EPS
    SELECT ticker, basic_eps, report_date
    FROM financial_statements
    WHERE (ticker, report_date) IN (
        SELECT ticker, MAX(report_date) 
        FROM financial_statements 
        GROUP BY ticker
    )
)
SELECT 
    lp.ticker,
    lp.latest_price,
    le.basic_eps,
    ROUND(lp.latest_price / NULLIF(le.basic_eps, 0), 2) as PE_Ratio
FROM LatestPrice lp
JOIN LatestEPS le ON lp.ticker = le.ticker
ORDER BY PE_Ratio ASC;

Query 6 Results: P/E Ratio Calculation

7. Stock Volatility

Calculates price volatility for each stock using standard deviation of closing prices.

Also shows average price, minimum and maximum prices during the period for context.

SQL Query 7
-- 7. Stock Volatility 
-- Calculate Standard Deviation of close price
SELECT 
    ticker,
    ROUND(AVG(close), 2) as avg_price,
    ROUND(STDDEV(close), 2) as price_volatility,
    MIN(close) as min_price_period,
    MAX(close) as max_price_period
FROM stock_prices
GROUP BY ticker
ORDER BY price_volatility DESC;

Query 7 Results: Stock Volatility Analysis

8. Moving Average for Apple (Calculating 30-Day Moving Average)

Calculates a 30-day moving average for Apple (AAPL) stock price using window functions.

Demonstrates technical analysis calculation for a specific stock.

SQL Query 8
-- 8. Moving Average for Apple (Calculating 30-Day Moving Average)
SELECT 
    ticker,
    date,
    close,
    AVG(close) OVER (
        PARTITION BY ticker 
        ORDER BY date 
        ROWS BETWEEN 29 PRECEDING AND CURRENT ROW
    ) as MA_30
FROM stock_prices
WHERE ticker = 'AAPL' 
ORDER BY date DESC
LIMIT 100;

Query 8 Results: Apple 30-Day Moving Average