Start Here

How to Write SQL Queries: A Complete Beginner's Guide

15 min readUpdated September 24, 2026Every example verified
On this page 14 sections ▾
  1. 1. What is a table, really?
  2. 2. What is SQL, and why does it exist?
  3. 3. Your very first query
  4. 4. Picking only the columns you need
  5. 5. Filtering rows with WHERE
  6. 6. Combining conditions
  7. 7. Sorting your results
  8. 8. Limiting how many rows you see
  9. 9. Summarizing data
  10. 10. Combining two tables
  11. 11. Changing data safely
  12. 12. Mistakes every beginner makes
  13. Practice this topic
  14. 13. Cheat sheet & what to learn next

This guide assumes you've never written a line of SQL in your life. We'll go slowly, one small idea at a time, and by the end you'll be able to write real queries yourself — not just copy them. Keep the SQL Playground open in another tab so you can type every example as we go. That's the fastest way to make it stick.

1. What is a table, really?

Before touching any SQL, get one picture firmly in your head: a database table looks exactly like a spreadsheet. If you've ever used Excel or Google Sheets, you already understand 90% of what a table is.

  • Each column is a category of information — like a spreadsheet column header (first_name, salary).
  • Each row is one single record — like one line in the spreadsheet (one employee, one order, one customer).
  • A table is the whole grid — all the rows and columns together, usually with a name like Employees.

Here's the actual Employees table you'll be practicing on — it's already loaded in the Playground:

emp_idfirst_namelast_namedept_idsalary
1AnanyaRao10142000
2MarcusBennett10118000
4TomasNowak20131000

(This is a small preview — the real table has 12 rows and a few more columns like email and hire_date.)

2. What is SQL, and why does it exist?

SQL (say it "S-Q-L" or "sequel") stands for Structured Query Language. It's simply the language you use to ask questions about the data in a table, or to change that data. Instead of scrolling through a spreadsheet with your eyes looking for rows that match, you write one sentence-like statement, and the database hands you exactly the rows you asked for — even if the table has ten million rows.

Every SQL sentence you write is called a query, or a statement. The five you'll use constantly are:

KeywordWhat it does
SELECTRead / retrieve data
INSERTAdd a new row
UPDATEChange existing rows
DELETERemove rows

We'll spend most of this guide on SELECT, because it's what you'll use 90% of the time — and everything else builds on the same ideas.

3. Your very first query

Open the Practice Playground, clear the editor, and type exactly this:

SELECT * FROM Employees;

Press Ctrl + Enter (or click Run Query). Let's break down what you just wrote, word by word:

  • SELECT — "I want to read some data."
  • * — the asterisk means "every column." Think of it as a wildcard meaning "all of them."
  • FROM Employees — "...and get it from the Employees table."
  • ; — the semicolon marks the end of the statement. Always end your queries with one.

Read out loud, this query says: "Select everything, from the Employees table." That's it — you just wrote and ran your first SQL query.

4. Picking only the columns you need

* is convenient, but in practice you rarely want every column. Instead, name the ones you actually want, separated by commas:

SELECT first_name, last_name, salary
FROM Employees;

Try it. You'll notice the result table now only has three columns instead of nine — you asked for exactly those, and that's exactly what came back. This is the core pattern of every SQL query you'll ever write: SELECT (what you want) FROM (where it lives).

5. Filtering rows with WHERE

So far every query returns all rows. To narrow it down to rows matching a condition, add a WHERE clause after FROM:

SELECT first_name, salary
FROM Employees
WHERE salary > 100000;
first_namesalary
Ananya142000
Marcus118000
Tomas131000
Priya105000
Chen156000

● 5 rows · produced by running this query on the sample database

Read it as: "Give me first_name and salary, from Employees, but only where salary is greater than 100000." The database checks the condition against every row, one at a time, and only keeps the ones where it's true. A few more examples to try:

WHERE dept_id = 10        -- exactly equal to 10
WHERE salary != 100000    -- not equal to
WHERE active = 1          -- only currently active employees

6. Combining conditions

Use AND when every condition must be true, and OR when just one needs to be:

SELECT first_name, dept_id, salary
FROM Employees
WHERE dept_id = 10 AND salary > 100000;
first_namedept_idsalary
Ananya10142000
Marcus10118000

● 2 rows · produced by running this query on the sample database

For the full picture on filtering — including matching text, checking ranges, and lists of values — see our dedicated WHERE clause guide once you're comfortable with the basics here.

7. Sorting your results

By default, rows come back in no particular order. Add ORDER BY to sort them:

SELECT first_name, salary
FROM Employees
ORDER BY salary DESC;

DESC means highest-to-lowest; drop it (or use ASC) for lowest-to-highest, which is the default.

8. Limiting how many rows you see

Combine ORDER BY with LIMIT to answer questions like "who are the 3 highest-paid employees?":

SELECT first_name, salary
FROM Employees
ORDER BY salary DESC
LIMIT 3;
first_namesalary
Chen156000
Ananya142000
Tomas131000

● 3 rows · produced by running this query on the sample database

Notice the order these clauses appear in — this order is fixed and always the same: SELECT → FROM → WHERE → ORDER BY → LIMIT. Writing them in a different order is a syntax error.

9. Summarizing data

Instead of looking at individual rows, you'll often want a summary — a total, an average, a count. These are called aggregate functions:

SELECT COUNT(*) AS total_employees, AVG(salary) AS avg_salary
FROM Employees;
total_employeesavg_salary
12101000

● 1 row · produced by running this query on the sample database

This collapses the whole table into a single summary row. To get a summary per group — like "average salary per department" — add GROUP BY:

SELECT dept_id, COUNT(*) AS headcount, AVG(salary) AS avg_salary
FROM Employees
GROUP BY dept_id
ORDER BY dept_id;
dept_idheadcountavg_salary
10599200
204100000
30168000
502124000

● 4 rows · produced by running this query on the sample database

This is a big enough topic to deserve its own guide — see GROUP BY vs HAVING when you're ready to go deeper.

Sample database schema Five tables. Orders references Customers via customer_id, Employees via emp_id, and Products via product_id. Employees references Departments via dept_id, and itself via manager_id for the reporting line. Customers customer_id PK company country city tier Employees emp_id PK first_name last_name dept_id FK manager_id FK salary Orders order_id PK customer_id FK emp_id FK product_id FK quantity order_date status order_total Products product_id PK name category unit_price in_stock Departments dept_id PK dept_name location budget
The whole sample database on one picture: solid arrows are foreign keys, and the dashed arrow is Employees.manager_id pointing back at its own table — the reporting line you join on in a self join.

10. Combining two tables

Real data is usually spread across several tables. For example, Employees stores a dept_id number, but the actual department name lives in a separate Departments table. A JOIN links them together by that shared column:

SELECT e.first_name, d.dept_name
FROM Employees e
JOIN Departments d ON d.dept_id = e.dept_id;

Here, e and d are short nicknames (aliases) for the two tables, so we can write e.first_name instead of the longer Employees.first_name. JOINs are one of the most important SQL skills — read the full JOINs guide next.

11. Changing data safely

So far we've only read data. These three statements change it — use them carefully, always with WHERE:

-- Add a new row
INSERT INTO Employees (emp_id, first_name, last_name, dept_id, salary, active)
VALUES (13, 'Nadia', 'Petrova', 10, 88000, 1);

-- Change existing rows
UPDATE Employees
SET salary = 95000
WHERE emp_id = 13;

-- Remove rows
DELETE FROM Employees
WHERE emp_id = 13;

The single most important habit to build: before running an UPDATE or DELETE, run the same WHERE condition as a SELECT first, and check the rows it returns. If you forget WHERE entirely, UPDATE and DELETE apply to every row in the table — there's no undo. (In the Playground, this is completely safe to experiment with — just click "Reset" in the sidebar to restore the sample data afterward.)

12. Mistakes every beginner makes

Using double quotes for text

Text values need single quotes: WHERE dept_name = 'Sales', not double quotes. Double quotes are for names of columns and tables. SQLite, which runs the Playground, lets "Sales" slide when no column has that name, and the Playground shows a warning when it does; PostgreSQL, and SQL Server with its usual settings, look for a column called Sales and fail.

Writing = NULL instead of IS NULL

NULL means "unknown," so it can never equal anything, even itself. Use IS NULL or IS NOT NULL instead.

Forgetting the clause order

It's always SELECT → FROM → WHERE → GROUP BY → HAVING → ORDER BY → LIMIT. Writing WHERE after ORDER BY, for example, is a syntax error.

Running UPDATE or DELETE without WHERE

Covered above, but worth repeating: no WHERE means every row is affected.

Practice this topic

Reading explains it; solving it is what makes it stick. These exercises use exactly what this page covered, and your answer is checked by running it against the same database:

See all 42 exercises →

13. Cheat sheet & what to learn next

SELECT column1, column2        -- what you want
FROM table_name                -- where it lives
WHERE condition                -- which rows
GROUP BY column                -- optional: collapse into groups
HAVING group_condition         -- optional: filter those groups
ORDER BY column ASC|DESC       -- optional: sort it
LIMIT n;                       -- optional: cap the row count

You now understand every piece of a real SQL query. From here, go deeper in this order:

  1. The SQL SELECT Statement: A Beginner's Guide — more on aliases and DISTINCT
  2. The SQL WHERE Clause — every filtering operator, including LIKE and BETWEEN
  3. SQL JOINs Explained — combining tables properly
  4. GROUP BY vs HAVING — summarizing data correctly
  5. SQL Subqueries Explained — queries inside queries
  6. 25 SQL Interview Questions — test what you've learned

Now go practice

Reading is step one. Open the Playground and retype every example in this guide yourself, from Step 3 onward — that repetition is what actually makes it stick.

Open the Playground

About the author

SQL Practice

SQL Practice publishes free SQL tutorials, an in-browser playground and 42 practice exercises, built so you can run what you read. Every runnable example in our tutorials is executed against the site’s sample database before it is published. Read how we keep tutorials accurate, or report a mistake.