SQLQuerying Databeginner
Updated:

The SELECT Statement in SQL

6 min read

The SELECT statement is the workhorse of SQL. Learn to pick columns, filter rows, sort results, and control how much data comes back.

TL;DR – Quick Answer

The SELECT statement reads data from one or more tables. You name the columns you want, use WHERE to filter rows, ORDER BY to sort them, and LIMIT to cap how many come back. It is the most-used statement in SQL, so mastering its clauses and their fixed order is the single highest-value SQL skill for beginners.

On This Page

The SELECT statement is how you read data out of a database, and it is the statement you will write more than any other. Everything from a login check to a monthly sales report is, underneath, a SELECT. Learn its clauses well and most of SQL falls into place.

This tutorial uses the same company schema as the rest of the series. If you have not met it yet, skim what is SQL first — it introduces the employees and departments tables we query below.

Our sample data

Here are the rows we will work with. Keep them in view as you read the queries.

-- employees
emp_id | emp_name | department_id | salary | city
-------+----------+---------------+--------+-----------
101    | Aarti    | 1             | 78000  | Hyderabad
102    | Bhaskar  | 1             | 65000  | Hyderabad
103    | Chitra   | 2             | 52000  | Bengaluru
104    | Devan    | 2             | 58000  | Bengaluru
105    | Esha     | 3             | 47000  | Hyderabad
106    | Farhan   | 4             | 90000  | Pune

The simplest SELECT

At minimum, a SELECT names the columns you want and the table they come from:

SELECT emp_name, salary
FROM employees;

This returns two columns and all six rows. If you want every column, SELECT * is a shortcut — handy while exploring, but you should name columns in real code so you fetch only what you use.

SELECT * FROM employees;

Common mistake: Reaching for SELECT * in application code. It pulls columns you do not need, breaks when someone adds a column, and hides your true intent. Always list the columns your code actually reads.

Filtering rows with WHERE

Most of the time you do not want every row — you want rows that meet a condition. That is the job of WHERE.

SELECT emp_name, city, salary
FROM employees
WHERE city = 'Hyderabad';

WHERE supports the comparison and logical operators you would expect:

-- salary in a range, in a specific department
SELECT emp_name, salary
FROM employees
WHERE salary BETWEEN 50000 AND 80000
  AND department_id = 1;

-- match several cities at once
SELECT emp_name, city
FROM employees
WHERE city IN ('Hyderabad', 'Pune');

-- pattern match: names starting with A or B
SELECT emp_name
FROM employees
WHERE emp_name LIKE 'A%' OR emp_name LIKE 'B%';

BETWEEN, IN and LIKE show up constantly. LIKE with % (any run of characters) and _ (a single character) is your basic text search, and it appears in interviews often.

Pro tip: To test for missing values, use IS NULL and IS NULL, never = NULL. In SQL, NULL means "unknown," and comparing anything to an unknown gives another unknown — so salary = NULL matches no rows, even the ones that are actually null.

Sorting results with ORDER BY

Databases do not promise any particular row order unless you ask. ORDER BY fixes the order, ascending by default or descending with DESC.

SELECT emp_name, salary
FROM employees
ORDER BY salary DESC;

You can sort by several columns. The database sorts by the first, breaks ties with the second, and so on:

SELECT emp_name, city, salary
FROM employees
ORDER BY city ASC, salary DESC;

This lists employees grouped by city alphabetically, and within each city, highest salary first.

Limiting how many rows come back

When you only need the top few results — the three highest earners, say — combine ORDER BY with LIMIT:

SELECT emp_name, salary
FROM employees
ORDER BY salary DESC
LIMIT 3;

This is exactly how "top N" reports are built. Note that LIMIT is MySQL and PostgreSQL syntax; SQL Server uses TOP and Oracle uses FETCH FIRST 3 ROWS ONLY. The differences between engines like these are covered in MySQL vs PostgreSQL.

Removing duplicates with DISTINCT

To see the unique values in a column, add DISTINCT:

SELECT DISTINCT city
FROM employees;

Against our data this returns three rows — Hyderabad, Bengaluru, Pune — even though six employees exist. DISTINCT applies to the entire selected row, so SELECT DISTINCT city, department_id gives unique combinations, not unique cities.

The clause order that explains everything

Beginners are often surprised that this query fails:

-- This does NOT work
SELECT emp_name, salary * 12 AS annual_pay
FROM employees
WHERE annual_pay > 600000;

The database complains that annual_pay does not exist in WHERE. The reason is that SQL clauses do not run in the order you write them. The logical execution order is:

Step Clause What it does
1 FROM Choose the source table
2 WHERE Filter individual rows
3 GROUP BY Collapse rows into groups
4 HAVING Filter groups
5 SELECT Compute output columns and aliases
6 ORDER BY Sort the result
7 LIMIT Cap the row count

Because SELECT runs at step 5 but WHERE runs at step 2, the alias annual_pay does not exist yet when WHERE is evaluated. The fix is to repeat the expression or use a subquery:

SELECT emp_name, salary * 12 AS annual_pay
FROM employees
WHERE salary * 12 > 600000;

Interview note: "What is the order of execution of a SQL query?" is one of the most reliable interview questions. Memorize the FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT sequence and be ready to explain why a SELECT alias is not visible in WHERE.

Column aliases and computed columns

You rarely display raw columns exactly as stored. SELECT lets you rename output columns with AS and compute new ones from expressions:

SELECT emp_name              AS name,
       salary                AS monthly_pay,
       salary * 12           AS annual_pay,
       salary * 0.10         AS pf_contribution
FROM employees;

The AS keyword renames a column purely in the output — it does not change the table. Aliases matter for readability and for the front-end code that consumes your result, which reads columns by name. You can drop AS (salary * 12 annual_pay) but keeping it makes intent obvious.

String and date functions work the same way, letting you shape data at read time rather than in application code:

SELECT UPPER(emp_name)              AS name_caps,
       LENGTH(emp_name)             AS name_length,
       CONCAT(emp_name, ' - ', city) AS label
FROM employees;

Doing this transformation in SQL keeps the logic close to the data and reduces the work your Java or JavaScript layer has to do.

Handling NULL safely

NULL means "no value recorded," and it behaves unlike any normal value. Any arithmetic with NULL yields NULL, and any comparison yields "unknown," so rows silently drop out of results. The COALESCE function gives you a fallback:

-- show 'Not set' instead of a blank for missing cities
SELECT emp_name,
       COALESCE(city, 'Not set') AS city
FROM employees;

COALESCE returns its first non-null argument, which is the standard way to substitute a default. Combined with IS NULL filtering, it covers almost every missing-data situation you will hit. NULL handling is a favorite interview trap precisely because it breaks the "everything is comparable" intuition beginners bring from other languages.

Putting it together

Real queries stack these clauses. Here is a request in plain English — "the two highest-paid employees based in Hyderabad, showing name and salary" — translated directly:

SELECT emp_name, salary
FROM employees
WHERE city = 'Hyderabad'
ORDER BY salary DESC
LIMIT 2;

FROM picks the table, WHERE keeps only Hyderabad rows, ORDER BY ranks them, and LIMIT keeps the top two. Once you can read a query and mentally trace it through the execution order, you are reading SQL the way professionals do.

Where to go next

A single-table SELECT is powerful, but real databases spread data across many tables. Your employees table, for example, only stores a department_id — to show the department name, you must combine it with the departments table.

That is the next skill: learn how to connect tables in SQL joins explained. After that, GROUP BY in SQL teaches you to summarize data, and the SQL interview questions for freshers let you test everything on the employees schema you now know well.

Frequently Asked Questions

What is the difference between SELECT and SELECT *?
SELECT * returns every column in the table, while SELECT with named columns returns only the ones you list. Naming columns is faster and clearer in real code because you fetch only the data you need. Use SELECT * only while exploring a table's contents.
In what order do SQL clauses execute?
You write SELECT first, but the database evaluates FROM, then WHERE, then GROUP BY and HAVING, then SELECT, then ORDER BY, then LIMIT. This logical order explains why you cannot use a column alias from SELECT inside WHERE. Understanding it clears up most beginner confusion.
How do I remove duplicate rows in a SELECT?
Add the DISTINCT keyword right after SELECT, as in SELECT DISTINCT city FROM employees. It collapses identical result rows into one. Note that DISTINCT applies to the whole selected row, not just one column.
What is the difference between WHERE and HAVING?
WHERE filters individual rows before grouping, while HAVING filters groups after GROUP BY has run. You use WHERE with raw column values and HAVING with aggregate results like COUNT or AVG. Using an aggregate in WHERE is a common error.
How do I limit the number of rows returned?
Use LIMIT in MySQL and PostgreSQL, as in SELECT ... LIMIT 5. SQL Server uses TOP and Oracle uses FETCH FIRST. All achieve the same goal of capping the result set to a fixed number of rows.

Want to Build Your Career in Java Full Stack with AI?

Join CodeBegun and train with working industry engineers — Explore the Program

Apply for Demo Class →
Siva Prasad Galaba
Founder, CodeBegun · Staff Engineer

Founder of CodeBegun. 15+ years building Java systems at companies like Crunchyroll. Teaches Java, Spring Boot and system design the way the industry actually works, and mentors students through projects, mock interviews and placement preparation.

Technically reviewed by CodeBegun Technical TeamLast reviewed 15 July 2026 LinkedIn
Chat with us