One dataset. Six tools. Let's build.
Every module below reuses the same 24-row Northside Bike Works repair-jobs dataset. Work through them in order โ each one ends with a live dashboard, hands-on exercises, a capstone project, and a quick auto-graded quiz.
The sample dataset
Here's what you'll be working with in every module โ a small repair-shop jobs log.
| JobID | Customer | JobType | Cost | Price | Date | Status |
|---|
(Showing the first 8 of 24 rows โ the full set loads automatically inside every module's live dashboard.)
Your 3-month path
Foundations
Excel and SQL โ the two skills nearly every analyst job posting asks for first.
Visual reporting
Google Sheets, Tableau and Power BI โ turning tables into dashboards people read.
Automation
Python and pandas โ so next month's report runs itself.
Excel
Formulas, conditional logic, lookups, and PivotTables.
1 Cells, references, and basic formulas
A cell is named by its column letter and row number (e.g. D2). A formula always starts with =.
=SUM(D2:D25) โ adds up the Cost column
=AVERAGE(E2:E25) โ average Price
=D2*1.2 โ Cost plus 20%
Relative vs. absolute reference is the single most common beginner trip-up. =D2*1.2 dragged down becomes D3, D4... automatically (relative). Lock a cell in place with dollar signs โ =D2*$H$1 โ and it always points at the same cell no matter where you copy it.
2 Conditional logic: IF, COUNTIF, SUMIF
=IF(G2="Complete", "Paid", "Chase Payment")
=COUNTIF(C2:C25, "Flat Repair") โ how many flat-repair jobs
=SUMIF(C2:C25, "Flat Repair", E2:E25) โ total revenue from flat repairs
Plain English: IF asks a yes/no question and gives a different answer for each. COUNTIF/SUMIF do the same across a whole column โ "count/total only the rows that match."
3 VLOOKUP and INDEX/MATCH
A separate Customers sheet lists each customer's city. Rather than retyping it next to every job, VLOOKUP fetches it automatically:
=VLOOKUP(B2, Customers!A:C, 3, FALSE)
"Take the customer ID in B2, look it up in the Customers sheet's first column, and bring back the value from the 3rd column, exact match only." INDEX/MATCH does the same job more flexibly. Learn VLOOKUP first โ it's the one you'll see in the wild.
4 PivotTables
This is where Excel stops being a calculator and starts being an analyst. Select your data โ Insert โ PivotTable. Drag JobType into Rows and Price into Values โ Excel instantly shows total revenue per job type, recalculating live if your data changes.
Exercises
- Build the sample Jobs table with 20+ rows of realistic mock data.
- Add a Margin column (Price โ Cost) with a formula, then a Margin % column.
- Use COUNTIF/SUMIF to find total revenue and job count per JobType.
- Build a PivotTable showing total Margin by JobType, plus a PivotChart.
- Add a Customers sheet and VLOOKUP each customer's city onto the Jobs sheet.
- Conditionally format Margin %: green above 40%, red below 20%.
Build a one-page Excel report: a PivotTable + chart showing which job types are most profitable, plus a formula-driven "Jobs still owed payment" list using IF. Export it to PDF as if sending it to yourself as a monthly summary.
Recap quiz
SQL
Asking a database a question in something close to plain English.
1 SELECT and WHERE
SELECT * FROM Jobs;
SELECT * FROM Jobs WHERE Status = 'Complete';
SELECT * FROM Jobs WHERE Price > 100 AND JobType = 'Full Tune-Up';
SELECT says what columns you want back; WHERE filters which rows qualify โ this maps directly onto Excel's Filter.
2 Aggregates and GROUP BY
SELECT JobType, SUM(Price) AS TotalRevenue, COUNT(*) AS JobCount
FROM Jobs
GROUP BY JobType
HAVING SUM(Price) > 100;
This is the SQL version of a PivotTable. HAVING filters groups after they're calculated, whereas WHERE filters rows before.
3 JOIN
This is the concept most people find hardest, so slow down here. A separate Customers table shares a CustomerID with Jobs. A JOIN stitches the two together:
SELECT Jobs.JobType, Jobs.Price, Customers.Name, Customers.City
FROM Jobs
INNER JOIN Customers ON Jobs.CustomerID = Customers.CustomerID;
"For every job, go find the matching customer row and bring its columns along too." This is exactly what VLOOKUP does in Excel โ a JOIN is VLOOKUP that can pull back a whole matching table at once. LEFT JOIN keeps every row from the first table even with no match in the second.
4 Building, not just reading
UPDATE Jobs SET Status = 'Complete' WHERE JobID = 3;
DELETE FROM Jobs WHERE JobID = 5;
Exercises
- Recreate the Jobs and Customers tables with CREATE TABLE + INSERT, 15โ20 rows each.
- Write a query for total revenue per customer.
- Write a JOIN query showing job type, price, and customer city together.
- Use CASE WHEN to label jobs "High Value" (>$100) or "Standard".
- Write a subquery: find the customer(s) whose total spend is above the average.
Model a 2โ3 table database and write 5 queries that answer real questions you'd want answered about the business โ e.g. "which customers haven't booked a job in 6+ months?"
Recap quiz
Google Sheets Analytics
Same skills as Excel, plus: it lives online.
1 QUERY(): SQL inside a spreadsheet
=QUERY(Jobs!A1:G, "SELECT C, SUM(E) WHERE G = 'Complete' GROUP BY C", 1)
This is literally SQL syntax living inside a cell โ total revenue (E) per job type (C), completed jobs only. If SQL made sense to you in Module 2, this will feel instantly familiar.
2 Live, shareable dashboards
IMPORTRANGE("sheet-url", "Jobs!A1:G") pulls live data from a separate spreadsheet. Share a sheet as "View only" so a client sees an always-current dashboard without being able to break your formulas. A Google Form feeding a Sheet gives you a free, live "New Enquiry" tracker.
3 ARRAYFORMULA
=ARRAYFORMULA(IF(E2:E100="", "", E2:E100 - D2:D100))
Instead of dragging one formula down 100 rows, this applies it to the whole range in one go, and keeps working as new rows are added by a Form.
Exercises
- Rebuild your Jobs sheet in Google Sheets; use QUERY() to reproduce your Excel PivotTable result.
- Build a Google Form ("New Enquiry") that feeds a Sheet automatically.
- Build a dashboard tab that summarises the Enquiries sheet live, with a chart.
- Share the dashboard as view-only and check it from an incognito window.
A Form for new jobs coming in, a Sheet storing them, and a dashboard tab summarising status and revenue โ shareable via a view-only link.
Recap quiz
Tableau
Proper drag-and-drop visual analytics.
1 Dimensions vs. Measures
This is the one idea Tableau hinges on. Dimensions are categories (JobType, Customer, Status โ things you group by). Measures are numbers you calculate (Price, Cost, Margin โ things you sum/average). Drag a Dimension onto Columns and a Measure onto Rows, and Tableau draws a chart automatically.
2 Building a dashboard
Connect to your CSV โ drag JobType to Columns, SUM(Price) to Rows โ instant bar chart. Drag Status onto Colour to split each bar. Add a Date filter, combine charts onto one Dashboard canvas, and add a "filter action" so clicking one chart filters the others.
3 Calculated fields
Margin = [Price] - [Cost]
Margin % = ([Price] - [Cost]) / [Price]
Same logic as an Excel formula, just written in Tableau's own box.
This is a "filter action" in miniature โ clicking a status chip filters the KPI cards and the chart together, exactly like clicking a mark on a real Tableau dashboard.
Exercises
- Connect your Jobs CSV and build a bar chart of revenue by JobType.
- Add a Calculated Field for Margin %, and colour-code jobs by it.
- Build a map of jobs by city.
- Combine all three into one Dashboard with a working filter.
- Publish it to Tableau Public and get a shareable link.
KPI numbers at the top (total revenue, total jobs, average margin), a chart by job type, and a map โ built from mock or real job data, published and shareable.
Recap quiz
Power BI
The enterprise standard many businesses already run on.
1 Power Query: cleaning data before you chart it
Power BI's built-in cleaning tool (Power Query Editor) lets you remove columns, fix data types, and rename fields before building any visual โ the step most people skip, then wonder why their chart looks wrong.
2 Relationships (same idea as a SQL JOIN)
Load Jobs and Customers, and Power BI needs to know they're connected โ draw a line between CustomerID in each table in Model view. Once that relationship exists, you can build a chart mixing fields from both as if they were one.
3 DAX basics
Total Revenue = SUM(Jobs[Price])
Total Margin = SUM(Jobs[Price]) - SUM(Jobs[Cost])
High Value Jobs = CALCULATE(COUNTROWS(Jobs), Jobs[Price] > 100)
Measures calculate on the fly based on what's filtered on screen. Calculated Columns compute a value for every row, stored permanently. When in doubt: if the number should change depending on what's filtered/selected, it's a Measure. CALCULATE recalculates a Measure under a different filter condition than what's on screen.
The status buttons act as a slicer โ every KPI card is a Measure recalculating live, exactly like CALCULATE() under a new filter.
Exercises
- Load Jobs and Customers; clean them in Power Query (types, renamed columns).
- Build the relationship between the two tables in Model view.
- Write DAX Measures for Total Revenue and Total Margin.
- Build a report page: bar chart by JobType, a KPI card, a slicer for Status.
- Publish to Power BI Service and share the link.
Rebuild your Module 4 Tableau dashboard in Power BI using the same data, then write a one-paragraph recommendation of which you'd suggest for a small-business client.
Recap quiz
Python
Stop repeating the same clean-analyse-chart routine by hand.
1 Variables, lists, and loops
job_prices = [90, 25, 450, 20, 30]
total = sum(job_prices)
print(f"Total revenue: ${total}")
for price in job_prices:
if price > 100:
print(f"High value job: ${price}")
A list is a column of data; a for loop repeats an action for every item โ same idea as dragging a formula down a spreadsheet column.
2 pandas: Python's version of a spreadsheet
import pandas as pd
jobs = pd.read_csv("jobs.csv")
jobs["Margin"] = jobs["Price"] - jobs["Cost"]
jobs.groupby("JobType")["Price"].sum() # the pandas PivotTable
jobs[jobs["Status"] == "Complete"] # the pandas filter
Every line here does something you've already done by hand in Excel and SQL โ pandas is just the fastest way to do it once your data gets big or repetitive.
3 Putting it together: an automated report
def summarise_jobs(csv_path):
jobs = pd.read_csv(csv_path)
jobs["Margin"] = jobs["Price"] - jobs["Cost"]
return jobs.groupby("JobType").agg(
TotalRevenue=("Price", "sum"),
AvgMargin=("Margin", "mean"),
JobCount=("JobID", "count")
).sort_values("TotalRevenue", ascending=False)
Run this on any month's export and get an instant summary โ no manual PivotTable rebuilding required.
summarise_jobs()
Exercises
- Load your Jobs CSV into pandas; add a Margin column.
- Recreate your Month 1 PivotTable result using .groupby().
- Build a bar chart of revenue by JobType using matplotlib.
- Write summarise_jobs() above and run it on your own data.
- Add a trend chart: total revenue by month, to spot seasonality.
Clean a dataset, summarise it in pandas, produce 2โ3 charts, and write a short plain-English paragraph of findings โ exactly the shape of a report a client would receive.
Recap quiz
Tying it all together
One question, answered four different ways.
Take one real (or realistic mock) dataset โ from your own work, or the Northside Bike Works set you've used throughout โ and produce the same summary four ways: an Excel PivotTable, a SQL query set, a Tableau or Power BI dashboard, and a Python script.
| Approach | Fastest to build? | Hand to a client? | Worth automating monthly? |
|---|---|---|---|
| Excel PivotTable | Usually yes, for <1,000 rows | If they already live in Excel | Rarely โ manual rebuild each time |
| SQL query set | Fast once tables exist | No โ needs a front-end on top | Yes, as a scheduled query |
| Tableau / Power BI dashboard | Slower to build, once | Yes โ this is what clients expect | Yes โ refreshes on its own |
| Python script | Slowest to write, once | Rarely directly | Yes โ the best long-term ROI |
Illustrative ratings to prompt your own judgement call โ the real answer depends on your data size, your client, and how often the report repeats.
- All 4 formats produce the same underlying numbers.
- You can say, out loud, which one you'd actually hand to a client โ and why.
- You can say which one you'd automate to run monthly โ and why.