SELF-GUIDED BA PRACTICE Selected editions available · Access after confirmed paymentCheck editions ↗

Data & SQL

SQL for business analysts

Data & SQL · Published · Updated · 11 min read · By BA Mentorship Editorial

What SQL is, in plain English

SQL (usually said "sequel" or "S-Q-L") stands for Structured Query Language. It is the standard way to ask questions of a relational database. A relational database stores information in tables, which look like spreadsheets: each column is one kind of fact (a name, an amount, a date) and each row is one thing (one customer, one loan, one order).

A query is a written question. Instead of clicking through a screen, you write "show me the loans that are late, biggest first" in a form the database understands, and it returns a small table of answers. Queries that only read data are safe: they do not change anything. In this guide every example is a read-only SELECT statement.

There are small differences between database products (SQLite, PostgreSQL, SQL Server, MySQL, Oracle), but the core you need as a business analyst is the same everywhere. The official SQLite documentation at sqlite.org/lang.html is a good free reference for the exact grammar.

Why a business analyst needs SQL

A business analyst sits between people who have a problem and people who build the solution. Many of those problems live in data: "late payments are rising", "customers are dropping out at checkout", "the report does not match the finance report". If you can only ask a developer for numbers, you wait, and you cannot tell whether the numbers are right. With basic SQL you can:

  • Understand the current situation before writing requirements: how many records, how many are in each status, how often something happens.
  • Check a problem statement against evidence: "Collections says late loans doubled" becomes a number you can see.
  • Write precise requirements: you know which table and which field holds a value, so you can say "use loans.status" instead of "the status thing".
  • Validate data during testing and migrations: duplicates, missing values, orphan records. This is called data validation.
  • Talk to developers and data teams as a peer, which speeds up every conversation.

You will not be asked to design a data warehouse on day one. Employers usually expect a junior analyst to read an existing database, write simple queries and explain what the results mean. If you want to see how this fits next to the other skills, read business analyst skills.

The sample data: Northwind Lending

Northwind Lending is a fictional small lender. Its operations manager, Ana, wants to understand late payments. Two tables hold what we need. customers lists people and loans lists each loan they hold. The column customer_id appears in both tables, and that is the link between them. In database words, customer_id is the primary key of customers and a foreign key in loans.

customers

customer_idnamecity
1Asha RaoPune
2Ben ColeLeeds
3Carla DiazMadrid
4Dev PatelLeeds
5Eli ParkSeoul

loans

loan_idcustomer_idamountstatusopened_on
101112000active2026-01-15
10215000closed2025-11-02
103220000active2026-03-10
10438000late2026-02-20
105415000active2026-04-05
10643000late2026-04-18
10727000closed2025-09-30

The data is invented for teaching. It is small enough that you can check every answer by eye, which is the best habit to build: predict the result before you run the query.

Step 1: SELECT, WHERE and ORDER BY

Every query starts with what you want to see (SELECT), where it comes from (FROM), and optionally which rows to keep (WHERE) and in what order (ORDER BY). Ana asks: "Which loans are active, biggest first?"

SELECT loan_id, customer_id, amount
FROM loans
WHERE status = 'active'
ORDER BY amount DESC;

Result:

loan_idcustomer_idamount
103220000
105415000
101112000

Read it aloud: "Show loan, customer and amount from loans where the status is active, with the largest amount first." Text values go in single quotes. DESC means largest first; ASC (the default) means smallest first. You can combine conditions with AND and OR, and compare with =, <> (not equal), >, <, BETWEEN and IN.

A tip for requirements work: avoid SELECT * in anything you share. Naming the columns documents exactly which fields matter, and that list often becomes the field list in your requirement.

Step 2: counting and totalling with GROUP BY

Most business questions are summaries: how many, how much, what share. COUNT, SUM, AVG, MIN and MAX are called aggregate functions. GROUP BY splits the rows into groups first and then summarises each group. Ana asks: "How many loans and how much money do we have in each status?"

SELECT status,
       COUNT(*)    AS loan_count,
       SUM(amount) AS total_amount
FROM loans
GROUP BY status
ORDER BY status;
statusloan_counttotal_amount
active347000
closed212000
late211000

Check by eye: active is 12000 + 20000 + 15000 = 47000. Good. AS gives a column a readable name, which matters when the result feeds a report.

To filter groups rather than rows, use HAVING. "Which customers hold more than one loan?"

SELECT customer_id, COUNT(*) AS loan_count
FROM loans
GROUP BY customer_id
HAVING COUNT(*) > 1
ORDER BY customer_id;
customer_idloan_count
12
22
42

The simple rule: WHERE filters rows before grouping, HAVING filters groups after. Another very common BA calculation is a percentage. "What share of all loans is late?"

SELECT ROUND(100.0 * SUM(CASE WHEN status = 'late' THEN 1 ELSE 0 END)
             / COUNT(*), 1) AS late_percent
FROM loans;

Result: 28.6 (2 late loans out of 7). The CASE expression turns each row into 1 or 0, and the 100.0 (with a decimal) stops the database from rounding the division down to a whole number. That last detail is a classic trap.

Step 3: joining two tables

Real questions use more than one table. Ana wants the names and cities of customers with late loans, but names live in customers and status lives in loans. A join lines up rows from two tables using the shared column.

SELECT c.name, c.city, l.loan_id, l.amount, l.status
FROM loans AS l
JOIN customers AS c ON c.customer_id = l.customer_id
WHERE l.status = 'late'
ORDER BY l.loan_id;
namecityloan_idamountstatus
Carla DiazMadrid1048000late
Dev PatelLeeds1063000late

The short names l and c are aliases that save typing. ON states the matching rule. A plain JOIN (an inner join) keeps only rows that match on both sides. To find customers with no loans, keep every customer and look for the gaps with a LEFT JOIN:

SELECT c.name
FROM customers AS c
LEFT JOIN loans AS l ON l.customer_id = c.customer_id
WHERE l.loan_id IS NULL;

Result: one row, Eli Park. We go deeper on join types, fan-out and the mistakes that produce wrong totals in SQL joins explained for business analysts. You can combine a join with grouping too: late loans per city gives Madrid with 1 loan worth 8000 and Leeds with 1 loan worth 3000.

Step 4: data validation checks a BA runs

Beyond answering questions, SQL lets you prove that data is trustworthy. Before you write a requirement that depends on a field, run a few quick checks. Each one is a short query where the "good" answer is zero rows or a known number.

  • Duplicate keys. SELECT loan_id, COUNT(*) AS copies FROM loans GROUP BY loan_id HAVING COUNT(*) > 1; should return no rows. It does here.
  • Orphan records. Loans whose customer does not exist: SELECT COUNT(*) AS loans_without_customer FROM loans AS l LEFT JOIN customers AS c ON c.customer_id = l.customer_id WHERE c.customer_id IS NULL; returns 0 here.
  • Missing values. COUNT(*) counts rows, COUNT(status) counts rows where status is not empty. If they differ, some statuses are blank.
  • Date range sanity. SELECT MIN(opened_on), MAX(opened_on) FROM loans; returns 2025-09-30 and 2026-04-18, which looks believable. A date in the year 1900 would be a red flag.
  • Allowed values. SELECT DISTINCT status FROM loans; should only show the statuses the business defined: active, closed, late. A stray "Late " with a trailing space would split your counts.

Combined in one line, the last two give total 7, with_status 7, first_open 2025-09-30, last_open 2026-04-18. These checks feed directly into acceptance criteria such as "Given a migrated loan, when I search by customer, then exactly one record is returned." See acceptance criteria examples for how to phrase them.

A step-by-step workflow for any data question

  1. Restate the question in business words. "Late" means what? Past due by how many days? Write the definition down before touching SQL.
  2. Find the tables and columns. Ask for a data dictionary or an entity relationship diagram. Look at ten raw rows first.
  3. Predict the answer roughly. About how many rows? A rough guess catches nonsense later.
  4. Build the query in small steps. Start with one table, then add the filter, then the join, then the grouping. Run it after each step.
  5. Check the result against a hand count on a small slice.
  6. Write down the definition and the query next to the number, so the next person can reproduce it. A documentation page or ticket comment is the right home.

This routine is the difference between "I ran some SQL" and "I can defend this number in a meeting".

Common mistakes and how to avoid them

  • ✅ Name your columns and alias your tables. ⚠️ SELECT * in a shared query hides which fields matter.
  • ✅ Write the business definition ("late = more than 30 days past due") next to the number. ⚠️ Quoting a figure without its definition invites an argument.
  • ✅ Use IS NULL to test for empty values. ⚠️ = NULL never matches anything, because NULL means unknown.
  • ✅ Check totals by hand on a small sample. ⚠️ Trusting a join result blindly; joins can multiply rows.
  • ✅ Use 100.0 or a cast when dividing. ⚠️ Integer division quietly returns 0 or a rounded-down answer.
  • ✅ Keep to read-only SELECT on real systems. ⚠️ Never run UPDATE or DELETE on production data unless it is your assigned job and you have a backup and approval.
  • ✅ Ask the data owner what a column really means. ⚠️ Guessing from the column name; status in one system rarely means what it means in another.

Try it yourself: a short exercise

Using the Northwind tables above, write queries for these three questions, then check your answers against the hints.

  1. List customers who live in Leeds, in alphabetical order by name. (Hint: two rows, Ben Cole then Dev Patel.)
  2. What is the total amount of closed loans? (Hint: 12000.)
  3. Show each customer's name with the number of loans they hold, including customers with none. (Hint: you need a LEFT JOIN and COUNT(l.loan_id); Eli Park should show 0.)

Then write one sentence on what a manager would do with each answer. Turning a result into a decision is the real BA skill.

How to practise SQL in the BA Lab

Reading about SQL is not the same as typing it. In the BA Lab, the Data & SQL stage (stage 6) puts you in a fictional company project with a task brief from a manager, tables to explore and a browser SQL console. The checks tell you whether your result matches the expected one and explain why a mismatch matters. It is a practice environment, not a production database, so you can experiment freely.

If you want extra drills first, the free page business analyst SQL practice has exercises, and the demo lets you look around. When you are ready for a full project, see the pricing page for which packages include the SQL stage. No course makes anyone job-ready by itself; consistent practice and a portfolio of explained work do.

Next, read SQL joins explained and business analyst vs data analyst to see where your SQL skills fit.

Frequently asked questions

How much SQL does a business analyst need?

Enough to read tables, filter with WHERE, summarise with GROUP BY, join two or three tables and run basic data checks. Most junior BA roles do not expect complex tuning or database design.

Is SQL hard to learn with no technical background?

The core is small and reads like English. Most beginners can write useful queries after a few focused practice sessions, especially on small tables where you can check answers by hand.

Which SQL dialect should I learn first?

Any. SELECT, WHERE, GROUP BY and JOIN work almost identically in SQLite, PostgreSQL, SQL Server and MySQL. Learn the core, then look up small differences when you meet a new system.

Can I break a real database with a SELECT query?

A plain SELECT only reads data. Very heavy queries can slow a busy system, so ask your data team which environment to use and keep queries targeted.

Do I need SQL if I only write requirements?

It helps a lot. Knowing the data lets you write precise requirements, spot impossible ones and validate results during testing.

This article is educational. All companies, people and numbers in the examples are fictional. BA Mentorship does not issue professional certifications and cannot guarantee any job or interview outcome.

Key terms in this article

Browse the full glossary

CHECK BEFORE CONTINUING

Keep your work safe