Fundamentals

The SQL SELECT Statement: A Beginner's Guide

7 min readUpdated September 24, 2026Every example verified
On this page 13 sections ▾
  1. The basic shape
  2. Choosing specific columns
  3. Renaming columns with AS
  4. Removing duplicates with DISTINCT
  5. Sorting results with ORDER BY
  6. Limiting how many rows come back
  7. Calculations in the SELECT list
  8. Joining text together
  9. Three mistakes worth avoiding early
  10. Putting it together
  11. Practice this topic
  12. Frequently asked questions
  13. Where to go next

Almost every SQL query you'll ever write starts with the same word: SELECT. It's how you ask a database to hand you rows of data. This guide walks through the SELECT statement piece by piece, using a simple Employees table as the running example. Every snippet below can be pasted straight into the SQL playground, which already has this exact table loaded.

The basic shape

A SELECT statement has two required parts: which columns you want, and which table to get them from.

SELECT column1, column2
FROM table_name;

To get every column without typing each name, use the asterisk wildcard:

SELECT * FROM Employees;

This is convenient while exploring a table, but in real applications it's better practice to name the columns you actually need — it makes the query's intent clear and avoids pulling data you'll never use.

Choosing specific columns

SELECT first_name, last_name, salary
FROM Employees;

The column order in your SELECT list controls the column order in the result — it doesn't need to match the table's original definition.

Renaming columns with AS

The AS keyword gives a column (or an expression) a friendlier name in the output, called an alias. It doesn't rename anything in the actual table.

SELECT
    first_name AS "First Name",
    salary AS annual_salary
FROM Employees;

Aliases are especially useful once you start using calculations or aggregate functions, where the raw expression makes an ugly column header:

SELECT
    first_name,
    salary,
    ROUND(salary * 12, 0) AS annual_salary
FROM Employees;

Removing duplicates with DISTINCT

If a column has repeated values and you only want to see each one once, add DISTINCT right after SELECT:

SELECT DISTINCT dept_id
FROM Employees;
dept_id
10
20
30
50

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

DISTINCT applies to the combination of every selected column, not each column independently. So SELECT DISTINCT dept_id, manager_id returns each unique pair of department and manager, not each unique department followed by each unique manager separately.

Sorting results with ORDER BY

Rows come back in no guaranteed order unless you ask for one. ORDER BY sorts ascending by default:

SELECT first_name, salary
FROM Employees
ORDER BY salary DESC;

Use ASC (default, so usually omitted) for low-to-high, and DESC for high-to-low. You can sort by multiple columns — the second column only breaks ties in the first:

SELECT dept_id, first_name, salary
FROM Employees
ORDER BY dept_id ASC, salary DESC;

Limiting how many rows come back

LIMIT caps the number of rows returned — handy for previewing a large table or grabbing a "top N" list once combined with ORDER BY:

SELECT first_name, hire_date
FROM Employees
ORDER BY hire_date DESC
LIMIT 3;
first_namehire_date
Daniel2023-04-03
Isabela2022-10-11
Hiroshi2022-02-14

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

That query returns the three most recent hires — LIMIT is evaluated after ORDER BY, so the sort happens first.

Calculations in the SELECT list

A SELECT list is not limited to columns that already exist. You can compute new ones from the row's values, and give the result a name with AS. Nothing is written back to the table — the calculation happens as the rows are returned:

SELECT name, unit_price, in_stock, unit_price * in_stock AS stock_value
FROM Products
ORDER BY stock_value DESC;
nameunit_pricein_stockstock_value
Beacon Analytics14509991448550
Atlas Cloud Suite899999898101
Harbor Support Plan400999399600
Aurora Laptop 14"12994254558
Vertex Monitor 27"449.996830599.32
Quill Keyboard11921024990
Nimbus Docking Hub189.513024635

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

Functions work here too. ROUND is a common one, because a raw multiplication or division often produces more decimal places than anyone wants to read:

SELECT name, unit_price, ROUND(unit_price * 0.9, 2) AS sale_price
FROM Products
WHERE category = 'Hardware';
nameunit_pricesale_price
Aurora Laptop 14"12991169.1
Vertex Monitor 27"449.99404.99

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

Joining text together

The standard SQL operator for gluing strings together is ||, which works in SQLite, PostgreSQL and Oracle. MySQL uses the CONCAT() function instead, and SQL Server uses +:

SELECT first_name || ' ' || last_name AS full_name, email
FROM Employees
ORDER BY full_name;

Note the ' ' in the middle. Without it you would get AnanyaRao — the operator joins exactly what you give it and adds nothing of its own.

Three mistakes worth avoiding early

Reaching for SELECT * out of habit

It is genuinely useful while exploring an unfamiliar table. In anything you intend to keep, name your columns. A saved query using * silently changes shape the day someone adds a column, and it moves far more data than the query actually needs.

Expecting a reliable order without ORDER BY

Rows come back in whatever order the database found convenient. It often looks sorted, which is precisely the trap — that apparent order is not a promise, and it can change when the data grows or an index is added. If order matters, say so explicitly.

Assuming DISTINCT applies to one column

SELECT DISTINCT a, b removes duplicate combinations of a and b, not duplicates of a. It is a modifier on the whole row the query returns, not on the column it happens to sit next to.

Putting it together

A more complete example, combining everything above:

SELECT
    first_name,
    last_name,
    dept_id,
    ROUND(salary, 0) AS salary
FROM Employees
ORDER BY salary DESC
LIMIT 5;
first_namelast_namedept_idsalary
ChenWei50156000
AnanyaRao10142000
TomasNowak20131000
MarcusBennett10118000
PriyaMenon20105000

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

Try it yourself

Open the SQL Playground — the Employees table is already loaded, so you can paste any query above and run it immediately.

Open the Playground

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 →

Frequently asked questions

What does SELECT * mean in SQL?

The asterisk is a wildcard meaning “every column in the table”. It is handy while exploring unfamiliar data, but in a query you intend to keep it is better to name the columns you actually want, so the result does not change shape when someone adds a column.

What is the difference between DISTINCT and GROUP BY?

DISTINCT removes duplicate rows from a result. GROUP BY collapses rows into groups so that aggregate functions can summarise each one. If you only want a de-duplicated list and no aggregates, DISTINCT states that intent more clearly.

How do I limit the number of rows returned?

Most databases use LIMIT, as in LIMIT 10. SQL Server uses SELECT TOP 10 instead, and Oracle uses FETCH FIRST 10 ROWS ONLY. A limit without an ORDER BY gives you an arbitrary ten rows rather than the first ten of anything meaningful.

Does the order of columns in SELECT matter?

Only for how the result is displayed — the columns come back in the order you list them. It has no effect on which rows are returned or on how the query is executed.

Can I use an alias defined in SELECT elsewhere in the same query?

In ORDER BY, yes, because ORDER BY runs after SELECT. In WHERE and HAVING it depends on the database, because in the standard those run before the aliases exist: PostgreSQL and SQL Server reject the alias in both, MySQL accepts it in HAVING but not in WHERE, and SQLite, which runs this site's playground, accepts it in both. Repeating the expression, or wrapping the query in a subquery, works everywhere.

Is SQL case-sensitive?

Keywords are not — SELECT and select are equivalent. Whether table and column names are case-sensitive depends on the database and, on some systems, the operating system. String values being compared are a separate question again, governed by collation.

Where to go next

Once SELECT feels comfortable, the next step is filtering rows with WHERE, then combining data from multiple tables with JOINs:

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.