SQL Learning Series · Part 1

SQL for Data Analysis: A Complete Beginner's Guide

Build database foundations, install PostgreSQL and DBeaver, create a working NovaMart database, and learn to retrieve, filter, sort, and limit data through real queries and practice assignments.

SQL for Data Analysis Foundations, stages 1 to 4
Four practical stages, from database vocabulary to reliable sorted results.
Published 16 August 2026Beginner levelEstimated study time: 5 hoursWritten by JENECONK

How to use this SQL guide

This guide is designed for a learner who has never queried a database. You do not need prior programming knowledge. Read Stage 1 before installing anything, complete the environment setup, and then type each query yourself. Reading SQL can make a command look familiar; running it, predicting the result, and correcting mistakes is what builds usable skill.

Every worked example uses the same NovaMart database so that concepts connect instead of appearing as isolated syntax. Five labels will help you navigate the learning process:

Facilitator note

A clear explanation an instructor can use to introduce a concept, or a solo learner can read before attempting the next example.

Best practice

A professional habit worth applying every time, such as naming columns explicitly or reading an error from the beginning.

Example

A complete query tied to a defined table, followed by an explanation of what the database returns.

Try it yourself

A short task to complete before continuing. Predict the result first whenever possible.

Watch for

A common mistake, why it happens, and the reliable way to correct it.

Stage 1: Database foundations

Goal: understand the system before writing queries.Learn databases, relational structure, data types, NULL, keys, relationships, and the basic shape of SQL.

What is a database?

A database is an organized collection of data stored so it can be searched, filtered, validated, and connected efficiently. A spreadsheet is excellent for small tables, calculations, and direct visual editing. A database becomes more useful when data grows, many people or systems rely on it, or one business process spans several related tables.

NeedSpreadsheetRelational database
Small list edited manuallyVery convenientPossible, but usually unnecessary
Connected customers and ordersOften requires repeated data or lookupsUses keys and relationships
Strict data validationCan be configured, but easily bypassedBuilt into the table structure
Repeatable analysisFormulas, filters, and pivotsSaved and reusable SQL queries
Large shared operational dataCan become slow or fragileDesigned for controlled access and scale

Relational databases and DBMS software

A relational database separates information into related tables. Instead of repeating a customer's name, state, email, and phone number on every order, one customers table stores the customer record and an orders table refers to that customer through an ID. The software that stores and manages these tables is called a database management system, or DBMS.

DBMSUseful context
PostgreSQLFree, standards-oriented, feature-rich, and widely used for analysis and applications.
MySQLFree and common in websites and web applications.
Microsoft SQL ServerCommon in Microsoft-centered enterprise environments.
SQLiteLightweight and file-based, useful for learning and embedded applications.

This guide standardizes on PostgreSQL. Most core statements transfer directly to other systems, although commands such as limiting rows can vary.

Tables, rows, columns, and data types

A table is one organized set of related data. A row, also called a record, is one complete entry. A column, also called a field, is one defined attribute stored for every row. Columns have data types, such as integer, text, date, decimal, or boolean. Data types help the database reject invalid input and handle sorting or calculations correctly.

Watch for: NULL is not zero

NULL means no value is recorded. It is different from numeric zero and different from an empty text string. A NULL order amount is unknown; an amount of 0 is known and confirmed to be zero.

Primary keys, foreign keys, and relationships

A primary key uniquely identifies each row in its own table and cannot be NULL. A foreign key points to a primary key in another table and creates a relationship. A unique key also prevents duplicate values, but it does not necessarily serve as the table's main row identifier.

  • One-to-one: one row in Table A matches one row in Table B.
  • One-to-many: one customer can have many orders. This is the most common business relationship.
  • Many-to-many: many students can take many courses, usually connected by an enrolment table.
Best practice: protect referential integrity

A foreign-key value should match a real primary key in the related table or be NULL when the relationship is optional. This prevents an order from pointing to a customer who does not exist.

What SQL is and how a query is structured

SQL stands for Structured Query Language. It is the language used to retrieve, filter, summarize, combine, and change relational data. Keywords have a defined order. Not every query uses every clause, but clauses that are present must appear in the right sequence.

SELECT column_name       -- what to retrieve
FROM table_name          -- which table
WHERE condition          -- which rows, optional
ORDER BY column_name;    -- how to sort, optional

SQL keywords are conventionally written in uppercase and table or column names in lowercase. PostgreSQL does not require that style, but consistency makes long queries easier to scan. Two dashes begin a line comment, and a semicolon marks the end of a statement.

Set up PostgreSQL and DBeaver

PostgreSQL is the database server that stores the data. DBeaver Community is the visible application used to connect to that server, browse tables, write queries, and inspect results. Install PostgreSQL first because DBeaver needs a database server to connect to.

Install PostgreSQL

  1. Visit postgresql.org/download and choose your operating system.
  2. Run the standard installer and keep the core components selected.
  3. Create a strong password for the postgres superuser and store it securely.
  4. Keep the default port 5432 unless another local service already uses it.
  5. Complete the installation. Stack Builder is optional and is not required for this guide.
Watch for: protect the superuser password

This is a local database administrator credential, not an ordinary website password. You will need it when connecting DBeaver. Do not publish, share, or reuse it on unrelated services.

Install and connect DBeaver

  1. Download DBeaver Community for Windows, macOS, or Linux.
  2. Open DBeaver and create a new database connection.
  3. Select PostgreSQL. Use host localhost, port 5432, username postgres, and your PostgreSQL password.
  4. Choose Test Connection. Allow DBeaver to download the PostgreSQL driver if requested.
  5. Finish the connection when the test reports success.

The Database Navigator displays connections, databases, schemas, and tables. The SQL Editor is where you write statements. A table's Data tab lets you inspect rows. In the editor, Ctrl+Enter on Windows or Cmd+Return on macOS runs the current statement.

SQL beginner troubleshooting table for PostgreSQL and DBeaver errors
Common setup and query errors become easier to solve when you read the message from the beginning.
Message or symptomLikely causeWhat to check
Connection refusedPostgreSQL is not runningStart or restart the PostgreSQL service, then reconnect.
Password authentication failedIncorrect passwordRe-enter the exact password; it is case-sensitive.
relation does not existWrong database, schema, or table spellingConfirm the editor is connected to novamart and inspect the Navigator.
column does not existColumn name is misspelledExpand the table and copy the actual column name.
syntax error at or nearMissing comma, quote, parenthesis, or keywordInspect the characters immediately before the word identified.

Build the NovaMart practice database

Create a database named novamart, open a fresh editor connected specifically to it, and then create two related tables. PostgreSQL does not use MySQL's USE database command; the editor's active connection determines where the statement runs.

NovaMart sample database with related customers and orders tables
NovaMart keeps customer details separate from orders and connects the tables through customerid.
CREATE DATABASE novamart;

After creating the database, refresh the Navigator, right-click novamart, and open a new SQL Editor. Then create and populate the tables:

CREATE TABLE customers (
  customerid INTEGER PRIMARY KEY,
  customername TEXT,
  state TEXT,
  gender TEXT,
  email TEXT
);

CREATE TABLE orders (
  orderid INTEGER PRIMARY KEY,
  customerid INTEGER REFERENCES customers(customerid),
  orderdate DATE,
  product TEXT,
  amount NUMERIC(10,2),
  salesperson TEXT
);
INSERT INTO customers VALUES
  (1, 'Adaeze Obi', 'Rivers', 'Female', 'adaeze.obi@mail.com'),
  (2, 'Tunde Bakare', 'Lagos', 'Male', 'tunde.bakare@mail.com'),
  (3, 'Chinyere Eze', 'Abuja', 'Female', 'chinyere.eze@mail.com'),
  (4, 'Ibrahim Musa', 'Kano', 'Male', 'ibrahim.musa@mail.com'),
  (5, 'Ngozi Umeh', 'Rivers', 'Female', 'ngozi.umeh@mail.com');

INSERT INTO orders VALUES
  (101, 1, '2025-01-12', 'Laptop', 450000.00, 'Amaka'),
  (102, 2, '2025-01-18', 'Monitor', 125000.00, 'Bello'),
  (103, 1, '2025-02-03', 'Keyboard', 35000.00, 'Amaka'),
  (104, 3, '2025-02-16', 'Printer', 185000.00, 'Chidi'),
  (105, 5, '2025-03-08', 'Router', 68000.00, 'Bello');

Expand novamart → Schemas → public → Tables and inspect each table's Data tab. If both tables display their rows, the practice environment is ready.

Stage 1 assignment: library schema

Create a library database with authors and books tables. Choose suitable data types, primary keys, and a foreign key from books to authors. Explain whether the relationship is one-to-one, one-to-many, or many-to-many.

Stage 2: Retrieve and filter data

Goal: write your first useful queries.Select columns, rename output, remove duplicates, filter rows, compare values, and combine conditions.

SELECT specific columns

SELECT names the columns the database should return. An asterisk asks for every column, while an explicit list returns only what the analysis needs.

SELECT *
FROM customers;

SELECT customername, state
FROM customers;
Best practice: avoid SELECT * in reusable work

An explicit column list documents the intended output, transfers less unnecessary data, and prevents a report from changing unexpectedly when a table gains another column.

Rename output with aliases

An alias changes a result heading without renaming the stored column. Use quotes when an output label contains spaces.

SELECT customername AS "Customer Name",
       state AS "Location"
FROM customers;

Remove duplicate results with DISTINCT

SELECT DISTINCT state
FROM customers;

NovaMart has five customer rows but only four distinct states. With several selected columns, DISTINCT evaluates the complete combination. Two rows collapse only when every selected value matches.

Filter rows with WHERE

SELECT orderid, product, amount
FROM orders
WHERE amount > 100000;
orderidproductamount
101Laptop450000.00
102Monitor125000.00
104Printer185000.00

Text and date literals need single quotes. Numeric values do not. Comparison operators include =, <> or !=, >, <, >=, and <=.

Combine conditions with AND, OR, and NOT

SELECT *
FROM orders
WHERE salesperson = 'Bello'
  AND amount > 50000;

AND requires every condition to be true. OR accepts a row when at least one condition is true. NOT reverses a condition. Use parentheses when combining AND and OR so the intended logic is unambiguous.

Stage 2 assignment: query the library

Add publication years and five book records. Return every column; return only title and genre with a readable title alias; and return the list of distinct genres. Predict whether adding authorid to the DISTINCT query will increase the number of rows.

Stage 3: Filter data properly

Goal: express real business conditions.Match lists, ranges, text patterns, missing values, and carefully grouped multi-condition filters.

Match a list with IN

SELECT customername, state
FROM customers
WHERE state IN ('Rivers', 'Lagos', 'Abuja');

IN is clearer than repeating the same column through several OR conditions. Text values need quotes; numeric values do not.

Match an inclusive range with BETWEEN

SELECT orderid, product, amount
FROM orders
WHERE amount BETWEEN 50000 AND 150000;

BETWEEN includes both boundaries. The same operator works with suitable date columns:

SELECT *
FROM orders
WHERE orderdate BETWEEN '2025-01-01' AND '2025-03-31';

Search text patterns with LIKE

PatternMeaning
'A%'Starts with A
'%son'Ends with son
'%market%'Contains market
'A_a'A, one character, then a
SELECT customername
FROM customers
WHERE customername LIKE 'A%';
Watch for: case sensitivity varies

PostgreSQL's LIKE is case-sensitive. Use ILIKE when you intentionally need PostgreSQL's case-insensitive matching. Other database systems handle case sensitivity differently.

Test missing values correctly

SELECT *
FROM customers
WHERE email IS NULL;

SELECT *
FROM customers
WHERE email IS NOT NULL;
Watch for: never use = NULL

WHERE email = NULL does not identify missing values. It evaluates to unknown and returns no matching rows. Also check whether the source system stores a true NULL or an empty string, because IS NULL does not match ''.

Combine several filters safely

SELECT *
FROM orders
WHERE salesperson IN ('Amaka', 'Bello')
  AND amount > 50000
  AND orderdate BETWEEN '2025-01-01' AND '2025-03-31';

Parentheses matter when OR is added. In the following query, the state alternatives are evaluated together before the amount condition:

SELECT *
FROM customers
WHERE (state = 'Rivers' OR state = 'Lagos')
  AND customerid > 1;
Stage 3 assignment: hotel bookings

Write queries for Deluxe or Suite rooms using IN; total cost between 50000 and 200000; guest names beginning with K; and bookings with no special request. Inspect the column first to determine whether missing requests are NULL or empty text.

Stage 4: Sort and limit results

Goal: answer ranked and priority questions.Control result order and return a deliberate top or bottom group.

Sort results with ORDER BY

SELECT product, amount
FROM orders
ORDER BY amount DESC;

Ascending order is the default. Add DESC for descending order. Multiple sort columns provide a predictable tiebreaker:

SELECT salesperson, product, amount
FROM orders
ORDER BY salesperson ASC, amount DESC;

Limit the number of rows

SELECT product, amount
FROM orders
ORDER BY amount DESC
LIMIT 3;

PostgreSQL, MySQL, and SQLite use LIMIT. SQL Server commonly uses TOP after SELECT. Pair the row cap with ORDER BY whenever the question asks for the highest, lowest, newest, oldest, best, or worst records.

Best practice: LIMIT needs ORDER BY

Without an explicit sort, a database does not promise which rows will appear first. LIMIT 10 alone means ten available rows, not the top ten.

Stage 4 assignment: leaderboard

Return the top three scores; resolve tied scores by sorting player name ascending as a second column; and return the single lowest score using ORDER BY and LIMIT rather than an aggregate function.

Worked assignment answers

Attempt each task before opening its solution. The struggle to recall and assemble a query is part of learning; recognizing an answer after it is revealed is not the same as producing it independently.

Stage 1 answer: library keys and relationship

bookid is the primary key of books and authorid is the primary key of authors. The authorid column in books is a foreign key referencing authors. This simple design is one-to-many: one author may have many books, while each book row points to one author.

Stage 2 answer: library queries
SELECT * FROM books;

SELECT title AS "Book Name", genre
FROM books;

SELECT DISTINCT genre
FROM books;

SELECT DISTINCT genre, authorid can return more rows because uniqueness is evaluated across each genre-author combination.

Stage 3 answer: hotel filters
SELECT * FROM bookings
WHERE roomtype IN ('Deluxe', 'Suite');

SELECT * FROM bookings
WHERE totalcost BETWEEN 50000 AND 200000;

SELECT * FROM bookings
WHERE guestname LIKE 'K%';

SELECT * FROM bookings
WHERE specialrequest IS NULL;
-- Use specialrequest = '' only when the source stores empty text.
Stage 4 answer: leaderboard sorting
SELECT * FROM leaderboard
ORDER BY score DESC
LIMIT 3;

SELECT * FROM leaderboard
ORDER BY score DESC, playername ASC;

SELECT * FROM leaderboard
ORDER BY score ASC
LIMIT 1;

The player-name tiebreaker makes the order predictable when two scores are equal.

SQL syntax cheat sheet

TaskSyntax
Select columnsSELECT col1, col2 FROM table;
Rename outputSELECT col AS alias FROM table;
Remove duplicatesSELECT DISTINCT col FROM table;
Filter rowsSELECT * FROM table WHERE condition;
Match a listWHERE col IN (value1, value2)
Match a rangeWHERE col BETWEEN low AND high
Match textWHERE col LIKE 'A%'
Find missing valuesWHERE col IS NULL
Sort resultsORDER BY col DESC
Cap rowsLIMIT 10
Add a comment-- comment text
Printable SQL syntax cheat sheet covering SELECT, DISTINCT, WHERE, IN, BETWEEN, LIKE, NULL, ORDER BY, and LIMIT
Keep the full quick-reference slide nearby while completing the assignments.

Frequently asked questions

What is the difference between a spreadsheet and a database?

A spreadsheet is convenient for smaller flat tables, direct editing, formulas, and presentation. A relational database is designed for connected tables, controlled data types, validation, repeatable queries, and larger shared data. Analysts commonly use both.

Why does WHERE column = NULL return nothing?

NULL is the absence of a recorded value, not an ordinary value. Comparisons with NULL evaluate as unknown. Use IS NULL or IS NOT NULL.

Do I need PostgreSQL to learn SQL?

No. The core concepts transfer to MySQL, SQL Server, SQLite, and other relational systems. PostgreSQL provides a capable free environment and gives every example in this guide one consistent syntax.

Is SQL case-sensitive?

SQL keywords are generally not case-sensitive, but text comparisons and object-name behavior vary by database. PostgreSQL folds unquoted identifiers to lowercase, and its LIKE operator is case-sensitive.

What should I learn next?

Continue with calculations, aggregate functions such as COUNT and SUM, GROUP BY, HAVING, data-cleaning functions, joins, subqueries, and complete analysis projects.

Continue your data-analysis pathway

This guide covers the first four stages of the JENECONK SQL learning series. Continue building your wider analyst toolkit through data cleaning in Excel, Power BI for business reporting, and the data analyst career roadmap. For guided practice, projects, and facilitator support, explore the JENECONK AI Training Academy.

JENECONK's training team developed this resource as a practical foundation for learners who need to move from spreadsheet familiarity into structured data work. Examples are written for hands-on use, and the guide will be expanded as later stages in the SQL series are published.

Study offline

Download the complete 50-slide SQL workbook.

The downloadable presentation contains the four-stage learning sequence, facilitator guidance, worked query/result pairs, assignments, answer keys, and the full reference sheet. The article above remains the complete web learning experience; the workbook is an optional study companion.

SQL stages 1 to 4 completion and next learning stages

Direct answer

What is SQL used for in data analysis?

SQL is used to retrieve, filter, combine, summarise and order data stored in relational databases. Analysts use it to turn structured records into answerable business questions.

Translate each question into four parts: required columns, source tables, row conditions and result order or summary. For example, “Which customers in Rivers State should appear alphabetically?” becomes a SELECT, FROM, WHERE and ORDER BY query.

Check syntax and behaviour against the official PostgreSQL query documentation. Continue from SQL to clean operational records, data-analysis resources and practical learning through the Academy.