SQL SELECT Statement – Syntax, Examples, and Query Order | DbSchema



Table of Contents

  1. What the SQL SELECT statement does
  2. SELECT syntax overview
  3. Logical query processing order
  4. SELECT specific columns vs SELECT *
  5. WHERE and DISTINCT
  6. Aliases, expressions, and CASE
  7. ORDER BY, LIMIT, TOP, and pagination
  8. GROUP BY, HAVING, and aggregate functions
  9. SELECT with JOINs and subqueries
  10. Common mistakes and best practices
  11. Build SELECT queries visually in DbSchema
  12. FAQ
  13. Conclusion

The SQL SELECT statement retrieves data from one or more tables. Almost every read query in SQL starts with SELECT, which is why it is the best place to learn how filtering, sorting, grouping, joins, and subqueries fit together.

Many beginner pages explain SELECT only as “choose columns from a table.” That is true, but incomplete. A real SELECT statement also shapes the result, controls the row set, and often powers applications, dashboards, exports, and APIs. This guide covers those practical pieces and shows how DbSchema helps you build and inspect queries visually.

What the SQL SELECT statement does

Use SELECT to:

  • choose columns
  • filter rows with WHERE
  • remove duplicates with DISTINCT
  • sort rows with ORDER BY
  • group rows with GROUP BY
  • filter grouped results with HAVING
  • combine tables with JOIN
  • nest queries with subqueries

Because all of those patterns live under one command, SELECT is the foundation for the rest of the SQL tutorial set.

SELECT syntax overview

SELECT [DISTINCT] column_list
FROM table_name
JOIN other_table ON condition
WHERE row_filter
GROUP BY grouping_columns
HAVING group_filter
ORDER BY sort_columns
LIMIT row_count OFFSET skip_count;

Not every clause is required. The simplest valid query is:

SELECT first_name, last_name
FROM customers;

Logical query processing order

One of the biggest sources of confusion is that SQL is written in one order but evaluated logically in another:

  1. FROM
  2. JOIN
  3. WHERE
  4. GROUP BY
  5. HAVING
  6. SELECT
  7. DISTINCT
  8. ORDER BY
  9. LIMIT / TOP / FETCH

That explains why:

  • aliases created in SELECT usually are not available in WHERE
  • HAVING filters grouped rows, not raw rows
  • ORDER BY sorts the final result set

SELECT specific columns vs SELECT *

Select only the columns you need

SELECT first_name, last_name, email
FROM customers;

This is usually better for readability, performance, and API stability.

Select all columns

SELECT *
FROM products;

SELECT * is fine for quick exploration, but it is risky in production because:

  • new columns can appear unexpectedly
  • sensitive columns may be returned accidentally
  • more data is transferred than needed

WHERE and DISTINCT

Filter rows with WHERE

SELECT first_name, last_name, salary
FROM employees
WHERE department = 'Engineering'
  AND salary > 70000;

Common WHERE operators include =, <>, >, <, BETWEEN, IN, LIKE, and IS NULL.

If you want a deeper walkthrough, continue with SQL WHERE Clause and SQL LIKE Operator.

Remove duplicates with DISTINCT

SELECT DISTINCT department
FROM employees;

DISTINCT works on the full combination of selected columns:

SELECT DISTINCT city, country
FROM customers;

For more examples, see SQL SELECT DISTINCT.

Aliases, expressions, and CASE

Column aliases

SELECT
  first_name || ' ' || last_name AS full_name,
  salary * 12 AS annual_salary
FROM employees;

Aliases make result sets easier to read, especially in reports and derived columns.

Expressions

SELECT
  product_name,
  price,
  price * 1.19 AS price_with_tax
FROM products;

CASE expressions

SELECT
  product_name,
  price,
  CASE
    WHEN price < 20 THEN 'Budget'
    WHEN price < 100 THEN 'Mid-range'
    ELSE 'Premium'
  END AS price_category
FROM products;

CASE lets you classify rows directly inside the query, which is common in dashboards and exports.

ORDER BY, LIMIT, TOP, and pagination

Sort the result set

SELECT first_name, last_name, hire_date
FROM employees
ORDER BY last_name ASC, hire_date DESC;

Limit returned rows

-- PostgreSQL, MySQL, SQLite
SELECT *
FROM products
ORDER BY price DESC
LIMIT 10;

-- SQL Server
SELECT TOP 10 *
FROM products
ORDER BY price DESC;

Paginate

SELECT *
FROM products
ORDER BY product_id
LIMIT 10 OFFSET 20;

If you paginate without a stable ORDER BY, page boundaries can shift unexpectedly. For a deeper sort guide, read SQL ORDER BY and SQL TOP, LIMIT, FETCH FIRST, and ROWNUM.

GROUP BY, HAVING, and aggregate functions

SELECT
  department,
  COUNT(*) AS employee_count,
  AVG(salary) AS average_salary,
  MAX(salary) AS max_salary
FROM employees
GROUP BY department;

GROUP BY creates one row per group. HAVING filters those grouped rows:

SELECT department, COUNT(*) AS employee_count
FROM employees
GROUP BY department
HAVING COUNT(*) > 5;

This is one of the most important transitions in SQL learning because it changes the result shape from detail rows to summary rows.

For deeper coverage, continue with SQL GROUP BY Explained, SQL HAVING Clause, and SQL COUNT, AVG, and SUM Functions.

SELECT with JOINs and subqueries

JOIN example

SELECT
  o.order_id,
  c.first_name,
  c.last_name,
  o.order_date,
  o.total_amount
FROM orders o
INNER JOIN customers c
  ON o.customer_id = c.customer_id
WHERE o.order_date >= '2024-01-01'
ORDER BY o.order_date DESC;

Subquery example

SELECT first_name, last_name, salary
FROM employees
WHERE salary > (
  SELECT AVG(salary)
  FROM employees
);

Derived-table example

SELECT department, avg_salary
FROM (
  SELECT department, AVG(salary) AS avg_salary
  FROM employees
  GROUP BY department
) AS department_stats
WHERE avg_salary > 80000;

Use joins when you need related columns from multiple tables. Use subqueries when a query depends on the result of another query. For more practice, read SQL Joins Explained.

Common mistakes and best practices

1. Using SELECT * everywhere

Great for exploration, poor for stable application queries.

2. Filtering aggregates in WHERE

This is wrong:

SELECT department, COUNT(*)
FROM employees
WHERE COUNT(*) > 5
GROUP BY department;

Use HAVING instead.

3. Forgetting ORDER BY during pagination

Without an explicit sort, the database is free to return rows in any order.

4. Confusing row filtering with group filtering

Use WHERE before grouping, HAVING after grouping.

5. Ignoring the schema

Many SELECT problems are really schema-understanding problems. DbSchema helps by keeping the relationships, keys, and table structures visible while you write the query.

Build SELECT queries visually in DbSchema

DbSchema includes a visual workflow for writing and understanding SELECT statements:

  1. Connect with the PostgreSQL JDBC driver, MySQL JDBC driver, or SQL Server JDBC driver.
  2. Inspect table relationships in the diagram before you write the query.
  3. Use the Query Builder to add tables, joins, filters, grouping, and sorting.
  4. Run the query and inspect the result in the Relational Data Explorer.
  5. Export the schema documentation if you need to explain the query context to teammates.

This is especially helpful for beginners because it connects the SQL text to the actual schema design, instead of treating the query as isolated syntax.

FAQ

What is the difference between WHERE and HAVING?
WHERE filters rows before grouping. HAVING filters groups after GROUP BY.

Can I use an alias in a WHERE clause?
Usually no, because WHERE is evaluated before SELECT. Use the full expression or wrap the query in a subquery.

What does SELECT * mean?
It returns all columns from the referenced tables. It is convenient for exploration but usually not ideal for production queries.

How do I select data from multiple tables?
Use explicit joins such as INNER JOIN or LEFT JOIN with an ON condition.

What is the default sort direction in ORDER BY? ASC is the default if you do not specify DESC.

Conclusion

The SQL SELECT statement is much more than a column picker. It is the framework that ties together filtering, sorting, grouping, joins, and subqueries. Once you understand the logical processing order, the rest of SQL becomes easier to reason about.

For next steps, continue with SQL WHERE Clause, SQL Joins Explained, and SQL ORDER BY.

DbSchema ER Diagrams & Team Collaboration

Desktop App for All OS
DbSchema ER Diagram Free Download
Visual Design & Schema Diagram

✓ Create and manage your database schema visually through a user-friendly graphical interface.

✓ Easily arrange tables, columns, and foreign keys to simplify complex database structures, ensuring clarity and accessibility.

GIT & Collaboration
Version Control & Collaboration

✓ Manage schema changes through version control with built-in Git integration, ensuring every update is tracked and backed up.

✓ Collaborate efficiently with your team to maintain data integrity and streamline your workflow for accurate, consistent results.

Data Explorer & Query Builder
Relational Data & Query Builder

✓ Seamlessly navigate and visually explore your database, inspecting tables and their relationships.

✓ Build complex SQL queries using an intuitive drag-and-drop interface, providing instant results for quick, actionable insights.

Interactive Documentation & Reporting
HTML5 Documentation & Reporting

✓ Generate HTML5 documentation that provides an interactive view of your database schema.

✓ Include comments for columns, use tags for better organization, and create visually reports.