Skip to main content
Data AnalyticsBeginner12 min readUpdated March 2025

SQL for Data Analysis

SQL is the analyst’s everyday tool for pulling answers out of databases. Learn the query building blocks — SELECT, WHERE, GROUP BY and ORDER BY — through realistic business questions.

The Shape of an Analytics Query

Most analysis questions reduce to: *filter some rows, group them, aggregate a measure, and sort the result.* SQL expresses each step with a clause:

  • SELECT — Choose columns and calculated measures.
  • FROM — The table (or joined tables) to read.
  • WHERE — Filter individual rows before grouping.
  • GROUP BY — Collapse rows into groups.
  • HAVING — Filter groups after aggregation.
  • ORDER BY / LIMIT — Sort and cap the output.

Answering a Business Question

*"Which product categories earned the most revenue in 2024, excluding cancelled orders?"*

sql
SELECT
    p.category,
    COUNT(DISTINCT o.order_id)          AS orders,
    SUM(oi.quantity * oi.unit_price)    AS revenue,
    ROUND(AVG(oi.unit_price), 2)        AS avg_price
FROM orders o
JOIN order_items oi ON oi.order_id = o.order_id
JOIN products p     ON p.product_id = oi.product_id
WHERE o.status <> 'cancelled'
  AND o.order_date >= '2024-01-01'
  AND o.order_date <  '2025-01-01'
GROUP BY p.category
HAVING SUM(oi.quantity * oi.unit_price) > 10000
ORDER BY revenue DESC
LIMIT 10;

Handling NULLs and Dates

Real data has gaps. Use `COALESCE` to supply defaults and date functions to bucket time:

sql
SELECT
    DATE_TRUNC('month', order_date)         AS month,
    COALESCE(region, 'Unknown')             AS region,
    COUNT(*)                                AS orders,
    SUM(total_amount)                       AS revenue
FROM orders
WHERE order_date >= CURRENT_DATE - INTERVAL '12 months'
GROUP BY 1, 2
ORDER BY 1, 2;

Habits of Good Analysts

Reliable numbers come from careful habits:

  • Check row counts after every join to catch accidental duplication.
  • Use explicit date ranges (>= start and < end) instead of BETWEEN for timestamps.
  • Alias every calculated column with a clear name.
  • Sanity-check totals against a known source before sharing.

Key Takeaways

  • Most questions are filter, group, aggregate, sort.
  • WHERE filters rows; HAVING filters groups.
  • Use COALESCE for NULLs and DATE_TRUNC for time buckets.
  • Always validate row counts and totals after joins.

Contact Us

Have a question or feedback? Fill out the form below or reach us directly at support@nvaitraining.com