>_ Analyst Engineering

SQL for Analysts: Query the State, Find the Truth

Cover for a guide on SQL for analysts, querying state to find the truth during analysis and testing.

SQL is the highest-leverage technical skill an analyst can have, not for building reports, but for querying the actual state of a system to find the truth. When you can read the data, you stop trusting documentation and start verifying reality.

The SQL a technical analyst needs is the SQL that reads state: SELECT to pull data, WHERE to filter it, JOIN to combine related tables, GROUP BY to summarize, and ORDER BY to sort. That small set lets you do the thing that matters most, confirm what a system is actually doing rather than what the documentation claims or a developer guesses. After you submit a payment, you query the table and see its real status and reason code. When the diagram says a field is optional, you query the data and find it is always populated. When the spec lists four statuses, you query the column and find nine. SQL is how an analyst stops trusting the story about the system and starts reading the system itself, which is why it sits at the center of the developer analyst toolkit.

I write SQL most weeks, and almost none of it is for reports. It is for answering questions during analysis and testing that I could otherwise only guess at. Being able to query state is the difference between an analyst who waits for someone to run a report and one who finds the answer in thirty seconds. This is the first skill I tell people to build, and the full progression is in The Technical Skills Guide for BAs.

What SQL does an analyst actually need?

An analyst needs a focused subset of SQL: SELECT, WHERE, JOIN, GROUP BY with aggregates, and ORDER BY, plus the ability to read an existing query. That covers the overwhelming majority of analysis and testing needs, and none of it requires a database background.

SELECT reads columns from a table, the foundation of everything. WHERE filters to the rows you care about, the specific payment, the failed transactions, the records from today. JOIN combines related tables, so you can pull the payment together with its account or its status history. GROUP BY with aggregate functions like COUNT, SUM, and MAX summarizes data, how many payments in each status, the total by currency, the latest timestamp per payment. ORDER BY sorts the result. Add a basic understanding of NULL, the absence of a value, which behaves differently than people expect and trips up filters, and you have the working vocabulary.

-- Read one payment's real state
select status, reason_code, created_at, settled_at
from payments
where uetr = 'abc-123';

-- How many payments in each status today
select status, count(*)
from payments
where created_at >= current_date
group by status
order by count(*) desc;

Notice what is not on the list: stored procedures, query optimization, schema design, window functions for their own sake. Those are the developer and DBA domain, and you can have a hugely productive analyst career without them. The goal is not to become a database engineer; it is to confidently answer questions about state, and the subset above does that. Reading an existing query you did not write is its own valuable skill, because half the time the answer is adapting a query someone already has.

How do you use SQL during testing?

You use SQL during testing to verify that an operation produced the correct state, by querying the database directly rather than trusting the user interface. The UI often hides, transforms, or simply does not show the underlying state, so checking the data is the only way to confirm what really happened.

The pattern is simple and constant. You perform an action, submit a payment, trigger a process, then query the table to assert the result. After a payment submission, you select its row and confirm the status is what you expect, the reason code is correct on a rejection and null on success, the timestamps are populated, the amount is stored correctly. This catches the defects the UI would hide: the status that shows “accepted” on screen while the database says something else, the reason code that is wrong underneath a generic message, the duplicate row that should not exist.

This is why SQL is inseparable from real testing. Much of a modern system’s behavior has no screen at all, the background processing, the event handling, the state transitions, and the only window into it is the database. An analyst who can query state can verify that behavior; one who cannot is limited to whatever the UI chooses to reveal, which is a fraction of the system. In payment testing specifically, querying the payments table to confirm the status and reason code is a step in nearly every test, and it is how you read the state machine the system actually implements versus the one the spec describes.

How do JOINs let you answer real questions?

JOINs let you answer questions that span more than one table, which is most real questions, because data in a normalized system is spread across related tables. A payment lives in one table, its account details in another, its status history in a third, and a JOIN brings them together.

The idea is to combine rows from two tables based on a related column, the key that links them. A payment row has an account id; the accounts table has the account details keyed by that id; a JOIN on the account id gives you the payment and its account in one result. This is how you answer questions like “show me the failed payments with the beneficiary account details” or “list each payment with its current status from the status table.” Without JOINs you are stuck querying one table at a time and stitching the results together by hand, which is slow and error-prone.

-- Failed payments with beneficiary account info
select p.uetr, p.amount, p.reason_code, a.account_number, a.status as acct_status
from payments p
join accounts a on a.id = p.creditor_account_id
where p.status = 'REJECTED';

You do not need to master every join type to be effective; understanding the basic inner join, which returns rows matching in both tables, handles most cases, and knowing that a left join keeps unmatched rows from the first table covers most of the rest. The mental model that matters is that your data is spread across related tables and a join reassembles it, which mirrors the data model you are already reasoning about as an analyst. Once joins click, the database opens up, because you can finally ask questions the way the business asks them, across entities rather than one table at a time.

How do you learn SQL as an analyst, fast?

Learn SQL by using it on a real system to answer real questions, not by grinding abstract tutorials. Get read access to a database, ideally a test environment or read replica, and start querying the things you actually need to know during your current work.

The fast path is deliberately practical. Begin with SELECT and WHERE on a table you care about, pulling a specific record and reading its fields. Add ORDER BY and basic WHERE conditions until filtering is comfortable. Then learn one JOIN by combining two tables you work with. Then GROUP BY by summarizing something you genuinely want to count. Each step is anchored to a real question from your work, which makes it stick in a way that a tutorial about a fictional schema never does. Within a couple of weeks of using it on real questions, you will be querying state confidently.

The mindset shift is the real payoff. Once you can query the data, your default for any question about system state changes from “ask someone” or “trust the doc” to “go look.” That self-sufficiency compounds across your whole career: you verify instead of assume, you find answers in seconds, and you catch the discrepancies between the documented system and the real one. It is the foundational skill of the developer analyst hat and the gateway to the others, scripting, reading APIs, reading logs, because they all build on the same comfort with reading a system directly. The structured path through all of them is The Technical Skills Guide for BAs, and the SQL-driven verification habit is the spine of how I test systems.

The takeaway

SQL is the highest-leverage technical skill for an analyst, because it lets you query the actual state of a system and find the truth instead of trusting documentation. You need a focused subset, SELECT, WHERE, JOIN, GROUP BY, ORDER BY, not the database-engineer depth. Use it constantly in testing to verify the real status and reason codes behind the UI, use JOINs to ask questions across related tables, and learn it by querying real systems for real answers.

Build this one skill and your default shifts from assuming to verifying, which changes how you work for the rest of your career. Start with The Technical Skills Guide for BAs, or browse everything at The Tech BA Toolkit.

Ahmed is a Senior Technical Business Analyst with 10+ years in banking and payments. He builds practical guides and tools for analysts at The Tech BA Toolkit.

Tags: SQL, Data Analysis, Technical Skills, Software Testing, Career Growth

Newsletter

Subscribe

Practical, no-fluff playbooks for technical analysts who analyze, code, test, and support. New articles straight to your inbox.

No spam. Unsubscribe anytime.