Advertisement
🚀 SQL Basics

SELECT Statement – Querying Data in SQL

The SELECT statement is the heart of SQL — it is the command you will write more than any other. Every time you want to read data from a database, you use SELECT. This lesson covers the core syntax, how to pick specific columns, write calculated expressions, and concatenate strings. All examples use a simple employees table so you can follow along and experiment immediately.

⏱️ 20 min read 🎯 Beginner 📅 Updated 2026

Basic SELECT Syntax

The minimal form of a SELECT statement requires two keywords: SELECT (what to retrieve) and FROM (where to retrieve it from).

SQL
SELECT column1, column2
FROM table_name;

SQL keywords are case-insensitive — SELECT, select, and Select all work. By convention, keywords are written in UPPERCASE to improve readability.

Throughout this lesson we use a practice employees table with the following columns:

ColumnTypeDescription
idINTUnique employee ID
first_nameVARCHARFirst name
last_nameVARCHARLast name
departmentVARCHARDepartment name
salaryDECIMALMonthly salary
hire_dateDATEDate hired

Selecting Specific Columns

List the column names separated by commas after SELECT. Only those columns appear in the result — this keeps output clean and avoids transmitting data you do not need.

SQL
-- Retrieve only name and department
SELECT first_name, last_name, department
FROM employees;

-- Retrieve only salary information
SELECT first_name, last_name, salary
FROM employees;
ℹ️
Comments in SQL

Single-line comments start with --. Multi-line comments use /* ... */. Use them freely to document your queries.

SELECT * — All Columns

The asterisk * is a wildcard that means "all columns". It is handy for exploration but should be used sparingly in production code.

SQL
-- Return every column from the employees table
SELECT * FROM employees;
⚠️
Avoid SELECT * in production

Using SELECT * retrieves all columns — even ones you do not need. This wastes network bandwidth, memory, and CPU. Always name the columns you need explicitly in application code. Reserve SELECT * for quick ad-hoc exploration in a database client.

You can also use SELECT without a table to evaluate an expression directly — useful as a calculator or to check database functions:

SQL
-- SQL as a calculator
SELECT 1 + 1;
-- Result: 2

-- Get the current date and time
SELECT NOW();
-- Result: 2026-06-08 14:30:00 (or similar)

Column Expressions

You can perform calculations inside a SELECT clause. The result is computed for every row and included in the output as a new (derived) column.

SQL
-- Calculate annual salary from monthly salary
SELECT first_name, last_name, salary * 12 AS annual_salary
FROM employees;

-- Calculate a 10% raise
SELECT first_name, salary, salary * 1.10 AS salary_with_raise
FROM employees;

-- Hypothetical order_items table: calculate line total
SELECT product_name, price, quantity, price * quantity AS total
FROM order_items;

The AS keyword gives the computed column a readable name (called an alias). You will learn more about aliases in a later lesson.

Advertisement

String Concatenation

Combining two text columns into one is called string concatenation. The syntax varies slightly between databases:

SQL
-- SQLite and PostgreSQL: use || operator
SELECT first_name || ' ' || last_name AS full_name
FROM employees;

-- MySQL: use CONCAT() function
SELECT CONCAT(first_name, ' ', last_name) AS full_name
FROM employees;

-- SQL Server: use + operator (or CONCAT)
SELECT first_name + ' ' + last_name AS full_name
FROM employees;
ℹ️
NULL and concatenation

In most databases, concatenating a NULL with any string produces NULL. For example 'Hello' || NULL returns NULL. Use COALESCE(column, '') to replace NULLs with an empty string before concatenating: COALESCE(first_name, '') || ' ' || COALESCE(last_name, '').

Column Order in SELECT

The order in which you list columns in a SELECT clause determines the order they appear in the result set — but it does not affect the underlying data or how the database processes the query. You can retrieve columns in any order, regardless of how they were defined in the table.

SQL
-- These two queries return identical data, just with columns in different order
SELECT first_name, last_name, department FROM employees;
SELECT department, last_name, first_name FROM employees;

Practice Queries

Try running these queries against the employees table to build your confidence:

SQL
-- 1. See all employees
SELECT * FROM employees;

-- 2. See only names
SELECT first_name, last_name FROM employees;

-- 3. See names and annual salary
SELECT first_name, last_name, salary * 12 AS annual_salary
FROM employees;

-- 4. Full name and department in one query
SELECT first_name || ' ' || last_name AS full_name, department
FROM employees;

-- 5. Quick math in SELECT (no table needed)
SELECT 100 * 12 AS twelve_hundred;

SQL Runs in a Different Order Than You Write It

You write SELECT first, but the database evaluates it almost last. Knowing the real order explains many "why can't I use my alias here?" errors.

Written orderLogical execution order
SELECT1. FROM / JOIN
FROM2. WHERE
WHERE3. GROUP BY
GROUP BY4. HAVING
HAVING5. SELECT (aliases created here)
ORDER BY6. ORDER BY
LIMIT7. LIMIT

Because SELECT runs at step 5, a column alias you define there doesn't exist yet in WHERE (step 2) — that's why WHERE total > 100 fails but ORDER BY total (step 6) works.

⚠️
SELECT * has real costs

It fetches every column (more network + memory), breaks if column order changes, prevents covering-index optimizations, and hides intent. In production, list the columns you actually need.

🏋️ Practical Exercise

  1. Select all columns from a table with SELECT *.
  2. Select only two specific columns.
  3. Add a constant column with SELECT 1 AS one.
  4. Select an expression such as price * quantity.
  5. Run a SELECT and note how many rows return.

🔥 Challenge Exercise

Write a query that returns only the name and email columns from a customers table (not SELECT *). Explain why selecting only the columns you need beats SELECT * for performance and clarity.

📋 Summary

  • Basic syntax: SELECT column1, column2 FROM table_name; — the foundation of every data query.
  • SELECT * retrieves all columns — useful for exploration, but avoid it in production code.
  • Specific columns: list column names separated by commas to retrieve only what you need.
  • Expressions: perform arithmetic directly in SELECT — e.g. salary * 12 AS annual_salary.
  • Concatenation: use || (SQLite/PostgreSQL) or CONCAT() (MySQL) to join string columns.
  • Column order in SELECT only affects output order, not query performance or data correctness.
  • SQL keywords are case-insensitive; uppercase convention improves readability.

Interview Questions

  • What does the SELECT statement do?
  • What is the difference between SELECT * and selecting specific columns?
  • Why is SELECT * discouraged in production?
  • What is the basic syntax of a SELECT query?
  • Can you SELECT a constant or an expression?

FAQ

What does SELECT * actually do? +

The asterisk * is a shorthand for "every column in the table". The database expands it to all column names when the query is executed. It is convenient for quick exploration in a database client (like MySQL Workbench or pgAdmin), but in application code you should always list columns explicitly. Reasons: it fetches unnecessary data, it breaks if columns are added or reordered, and it obscures what data your code actually depends on.

Does column order in SELECT affect performance? +

No. Reordering columns in your SELECT list has no impact on query performance. The database reads the same rows and the same data regardless of the column order you specify. Order only affects how the result set is presented to your application or query tool.

Is SQL case-sensitive? +

SQL keywords (SELECT, FROM, WHERE, etc.) are case-insensitive — select and SELECT are identical. However, string data in comparisons may or may not be case-sensitive depending on the database and collation settings. For example, in MySQL the default collation is case-insensitive for string comparisons, while PostgreSQL is case-sensitive by default. Always check the collation of your database when doing string comparisons.

Do I need a semicolon at the end of a SQL statement? +

In most database clients and when running scripts with multiple statements, the semicolon ; is required to terminate each statement. When running a single query interactively (e.g. in MySQL Workbench or a programming language driver), it is often optional. As a best practice, always include the semicolon — it prevents errors when you later combine queries into a script.