Why SQL matters for BI Analysts
SQL is the language that turns raw tables into decision-ready metrics. As a BI Analyst, you will use SQL to define KPIs, join fact and dimension tables, power dashboards, run adâhoc investigations, and validate data quality. Strong SQL gives you speed and confidence when stakeholders ask for a new metric, a trend breakdown, or the root cause behind a change.
- Turn business questions into precise queries
- Build reliable, reusable views for BI tools
- Create timeâseries trends, rankings, and cohortâstyle insights
- Optimize queries for dashboard refreshes and data loads
Practical roadmap
Step 1 â Retrieval and Filtering
- Select specific columns, filter with WHERE, and sort with ORDER BY
- Translate KPI definitions into column logic (CASE, COALESCE)
Step 2 â Joins and Data Modeling
- Join fact tables (events, orders) to dimensions (customers, products)
- Understand keys, one-to-many joins, and how to avoid duplication
Step 3 â Aggregations and KPI Logic
- Summaries with GROUP BY and HAVING
- Distinct counts, conditional sums, and ratio metrics
Step 4 â Window Functions and Time Intelligence
- Rankings, rolling averages, period-over-period comparisons
- Calendar tables, date truncation, and gap-filling
Step 5 â Reusable Views for BI
- Encapsulate KPI logic into views for dashboards
- Add comments, stable column names, and version-friendly patterns
Step 6 â Performance & Reliability
- Filter early, aggregate before joining where possible
- Use explain plans (if available), limit scanned data, and validate results
Worked examples (BI-focused)
Example 1 â Daily Active Customers (last 30 days)
-- Tables: customer_events(customer_id, event_date, event_type)
SELECT
event_date,
COUNT(DISTINCT customer_id) AS daily_active_customers
FROM customer_events
WHERE event_date >= CURRENT_DATE - INTERVAL '30 days'
GROUP BY event_date
ORDER BY event_date;
Tip: Always specify the date window to keep queries fast and relevant.
Example 2 â Revenue by Segment (Fact + Dimensions)
-- Tables: orders(order_id, customer_id, order_date, total_amount)
-- customers(customer_id, segment)
SELECT
c.segment,
DATE_TRUNC('month', o.order_date) AS month,
SUM(o.total_amount) AS revenue
FROM orders o
LEFT JOIN customers c ON o.customer_id = c.customer_id
GROUP BY c.segment, DATE_TRUNC('month', o.order_date)
ORDER BY month, c.segment;
Why LEFT JOIN? You keep valid orders even if the customer dimension is missing a row.
Example 3 â KPI with GROUP BY and HAVING
-- Monthly product revenue with a minimum threshold for reporting
-- Tables: order_items(order_id, product_id, qty, unit_price), orders(order_id, order_date)
SELECT
DATE_TRUNC('month', o.order_date) AS month,
oi.product_id,
SUM(oi.qty * oi.unit_price) AS product_revenue
FROM order_items oi
JOIN orders o ON o.order_id = oi.order_id
GROUP BY month, oi.product_id
HAVING SUM(oi.qty * oi.unit_price) >= 1000
ORDER BY month, product_revenue DESC;
HAVING filters after aggregation. Use it for thresholds on aggregated metrics.
Example 4 â Rolling 7âday Revenue and DayâoverâDay Change
-- Table: daily_revenue(date_day, revenue)
SELECT
date_day,
revenue,
SUM(revenue) OVER (
ORDER BY date_day
ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
) AS rolling_7d_revenue,
revenue - LAG(revenue) OVER (ORDER BY date_day) AS revenue_dod_change
FROM daily_revenue
ORDER BY date_day;
Window frames let you create smooth trends and comparisons without extra joins.
Example 5 â Handling Nulls and Deâduping
-- Prefer the latest non-null attribute per customer
-- Table: customer_attributes(customer_id, email, updated_at)
WITH ranked AS (
SELECT *,
ROW_NUMBER() OVER (
PARTITION BY customer_id
ORDER BY updated_at DESC
) AS rn
FROM customer_attributes
)
SELECT customer_id,
COALESCE(email, 'unknown@example.com') AS email
FROM ranked
WHERE rn = 1;
ROW_NUMBER deâduplicates; COALESCE gives safe defaults for downstream dashboards.
Example 6 â Reusable KPI View for BI
-- Create a view that BI tools can query directly
-- Tables: orders(order_id, order_date, customer_id, total_amount)
-- customers(customer_id, segment)
CREATE OR REPLACE VIEW v_monthly_segment_revenue AS
SELECT
DATE_TRUNC('month', o.order_date) AS month,
c.segment,
SUM(o.total_amount) AS revenue,
COUNT(DISTINCT o.customer_id) AS unique_buyers
FROM orders o
LEFT JOIN customers c ON c.customer_id = o.customer_id
GROUP BY month, c.segment;
Keep view columns stable and documented. This reduces breakage across dashboards.
Drills and exercises
- â Write a query to get weekly active users (WAU) for the past 12 weeks.
- â Calculate average order value (AOV) per segment per month.
- â Produce a topâ10 products list by revenue in the last quarter.
- â Create a 30âday rolling average of signâups.
- â Deduplicate customer emails, keeping the most recent record only.
- â Turn your most used KPI into a CREATE VIEW statement.
- â Optimize a slow query by pushing filters to the earliest possible step.
Common mistakes and debugging tips
Counting duplicates after joins
Symptom: metrics double. Fix: aggregate fact tables before joining, or join dimensions first then aggregate once.
Using WHERE instead of HAVING for aggregated conditions
WHERE filters rows before aggregation; HAVING filters after aggregation. Use HAVING to filter sums, counts, or averages.
Incorrect time grouping
Always normalize to a grain (e.g., DATE_TRUNC('month', ts)) before grouping or joining to date dimensions.
Window frame surprises
Default frames may differ by SQL dialect. Specify ROWS/RANGE frames explicitly for rolling metrics.
NULLs breaking ratios
Use COALESCE around denominators and CASE for safe division. Example: CASE WHEN denom > 0 THEN num::decimal/denom END.
Unbounded scans
Always filter by date when possible to reduce the amount of data scanned.
Mini project: Executive KPI Dashboard Backbone
Goal: Build a reliable SQL layer that powers a dashboard for Revenue, Active Customers, AOV, and Top Products.
- Define KPIs and grain: daily and monthly.
- Write base queries: daily active customers, daily revenue, monthly AOV, top products last 90 days.
- Create views: v_daily_kpis, v_monthly_kpis, v_top_products.
- Data quality checks: compare sums against raw tables; spotâcheck a few days manually.
- Performance: add date filters in each view; aggregate before joining; only select needed columns.
- Handoff: provide column descriptions and example queries BI tools can use.
Expected deliverables
- 3â4 CREATE VIEW statements with clear column names
- Sample queries that demonstrate the KPIs
- A short note on assumptions and edge cases (NULLs, late-arriving data)
Subskills
Writing KPI Queries For Dashboards
Translate business metrics into SELECT statements with clear filters, safe math, and consistent grains.
Joins Across Fact And Dimension Tables
Combine facts with dimensions safely, avoiding duplicate counts and preserving completeness with the right join type.
Aggregations Group By Having
Summarize data correctly, filter aggregated results, and build threshold logic for reporting.
Window Functions For Rankings And Trends
Create rankings, rolling metrics, and period comparisons without extra joins.
Building Reusable Views For BI
Package KPI logic into stable, documented views that dashboards can reuse.
Date Handling For Time Series
Use date truncation, calendars, and gap-filling to produce trustworthy time-based metrics.
Handling Nulls And Duplicates
COALESCE, CASE, and ROW_NUMBER patterns that keep downstream metrics consistent.
Query Optimization For BI Loads
Filter early, aggregate early, select only needed columns, and keep refresh times predictable.
Who this is for
- Aspiring or current BI Analysts who need reliable, dashboardâready SQL
- Dataâcurious professionals who support metric tracking and reporting
Prerequisites
- Comfort with basic spreadsheets or charts
- Familiarity with business metrics (revenue, conversion, retention)
- Optional: a basic understanding of star schemas
Learning path
- SQL foundations for BI (filters, joins, aggregations)
- Time series and window functions
- Reusable views and data quality checks
- Performance optimization for BI refresh cycles
- Layer into a BI tool (naming conventions, stable schemas)
Practical projects
- Marketing funnel KPIs with weekly trends
- Sales performance dashboard base tables and views
- Product engagement rankings with rolling metrics
Next steps
Practice with the drills, complete the mini project, then take the skill exam to validate your knowledge. The exam is available to everyone; loggedâin users have their progress saved.