MySQL
POSTGRESQL
SQL
SQL SERVER

SQL Derived Table: Everything You Need to Know

intro

Let’s explore everything you need to know about the SQL derived table mechanism—a way to create virtual tables within the FROM clause.

Tools used in the tutorial
Tool Description Link
Dbvisualizer DBVISUALIZER
TOP RATED DATABASE MANAGEMENT TOOL AND SQL CLIENT

Sometimes, the data you need is not stored in a single table. Instead, you may need to retrieve it through aggregations, multiple joins, or advanced filtering. The solution? An SQL derived table—a temporary, inline table created within a query for simplified data retrieval.

In this article, you will learn what a derived table is in SQL, how to use it effectively, and when it can be most helpful.

Let’s dive in!

What Is a Derived Table in SQL?

A derived table is an SQL expression that generates a table within a FROM clause of a query. In other words, it is a temporary result set created on the fly during the query execution and used in the FROM clause.

Derived tables support complex operations like joins, filtering, and aggregation without needing to create permanent tables. Once the query finishes its execution, the derived table is discarded as it is not persisted in the database. So, an SQL derived table is essentially a subquery that acts like a virtual table for the duration of the query execution. Learn more in our guide about SQL subqueries and for specific details, refer to the documentation links:

Derived Table SQL Syntax and Characteristics

This is the syntax for creating derived tables in standard SQL:

Copy
        
1 SELECT ... 2 FROM (subquery) [AS] derived_table_name 3 [WHERE ...]

Where:

  • subquery is the SQL subquery used to define the derived table;
  • derived_table_name is the name given to the derived table.

Notes:

  • [AS] derived_table_name is required because every table or derived table used in the FROM clause must have a name. Discover more in our guide on the SQL alias mechanism.
  • The derived table created with subquery represents the result set to select data from and can be treated like a regular table in the outer query. For example, the columns and values selected in the derived table can indeed be used in the WHERE, GROUP BY, HAVING, and ORDER BY clauses of the outer query.

Let's now explore what specific DBMS technologies offer when it comes to derived tables.

MySQL

MySQL provides another way to create a derived table via the JSON_TABLE() function:

Copy
        
1 SELECT ... 2 FROM JSON_TABLE(arg_list) [AS] derived_table_name 3 [WHERE ...]

If you are not familiar with that function, JSON_TABLE() extracts data from a JSON document and returns it as a relational table having the specified columns.

For example, you can use it as below:

Copy
        
1 SELECT employee_id, name, salary 2 FROM JSON_TABLE( 3 '[{"employee_id": 1, "name": "Alice", "salary": 50000}, 4 {"employee_id": 2, "name": "Bob", "salary": 60000}]', 5 "$[*]" COLUMNS ( 6 employee_id INT PATH "$.employee_id", 7 name VARCHAR(50) PATH "$.name", 8 salary DECIMAL(10, 2) PATH "$.salary" 9 ) 10 ) AS employee_data 11 WHERE salary > 55000;

The above query populates a derived table with employee data from a JSON string. Then, it retrieves all employees whose salary is greater than 55000.

Notes:

  • A derived table cannot contain references to other tables of the same SELECT. To cover that use case, you need instead a LATERAL derived table.
  • The MySQL optimizer can determine information about derived tables in such a way that the EXPLAIN does not need to materialize them. Find out more in our article on SQL EXPLAIN.

PostgreSQL

There are the aspects to keep in mind when using derived tables in PostgreSQL:

  • Subqueries specifying a derived table must be enclosed in parentheses
  • They can optionally be assigned column alias names

An example of a derived table SQL definition query with column alias names is:

Copy
        
1 SELECT dept_name, avg_salary 2 FROM ( 3 SELECT department_id, AVG(salary) 4 FROM employees 5 GROUP BY department_id 6 ) AS dept_avg(dept_id, avg_salary) 7 JOIN departments ON departments.id = dept_avg.dept_id 8 WHERE avg_salary > 50000;

Here, department_id and AVG(salary) are renamed as dept_id and avg_salary, respectively.

SQL Server

Here are the key characteristics of derived tables in SQL Server:

  • Like in PostgreSQL, they must be enclosed in parentheses, and column aliases can optionally be assigned
  • The Transact-SQL table value constructor can be used to define a derived table

Here is an example of using the table value constructor to list rows and columns directly within the derived table SQL Server definition:

Copy
        
1 SELECT employee_id, name, salary 2 FROM ( 3 VALUES 4 (1, 'Alice', 50000), 5 (2, 'Bob', 60000), 6 (3, 'Carol', 55000) 7 ) AS employees(employee_id, name, salary) 8 WHERE salary > 55000;

Use Cases for an SQL Derived Table

A derived table in SQL can be used in a variety of scenarios. Time to analyze two of the most useful ones!

1. Aggregating Data for Filtering in Outer Queries

In some scenarios, you need to filter records based on aggregate values. Derived tables can simplify this process by enabling you to calculate aggregates inline and use them in the WHERE clause of the main query.

For example, the following query retrieves the employees who earn more than the average salary in their department:

Copy
        
1 SELECT e.id, e.name, e.salary, dept_avg.avg_salary 2 FROM ( 3 SELECT department_id, 4 AVG(salary) AS avg_salary 5 FROM employees 6 GROUP BY department_id 7 ) dept_avg 8 JOIN employees e ON e.department_id = dept_avg.department_id 9 WHERE e.salary > dept_avg.avg_salary;

2. Simplifying Complex JOINs

When working with multiple tables, an SQL derived table can be used to greatly simplify complex JOIN statements by encapsulating part of the query logic in a virtual table. The resulting query will be easier to read and manage.

For instance, this query retrieves the list of employees along with their department names and the region of their department location, assuming the region of their department is in America:

Copy
        
1 SELECT e.id AS employee_id, 2 e.name AS employee_name, 3 dept_locations.department_name, 4 r.name AS region_name 5 FROM employees e 6 JOIN ( 7 SELECT d.id AS department_id, 8 d.name AS department_name, 9 l.region_id AS region_id 10 FROM departments d 11 JOIN locations l ON d.location_id = l.location_id 12 WHERE l.name = 'America' 13 ) dept_locations ON e.department_id = dept_locations.department_id 14 JOIN regions r ON dept_locations.region_id = r.region_id;

First, the query creates a derived table called dept_locations that includes department names and region IDs, filtering for locations in America. Then, it joins it with the employees table to retrieve employee information.

While it is longer, some users may find the above query easier to follow than the equivalent one below due to its formatting:

Copy
        
1 SELECT e.id AS employee_id, 2 e.name AS employee_name, 3 d.name AS department_name, 4 r.name AS region_name 5 FROM employees e 6 JOIN departments d ON e.department_id = d.id JOIN locations l ON d.location_id = l.location_id JOIN regions r ON l.region_id = r.region_id 7 WHERE l.name = 'America';

More Readable Queries With DbVisualizer

As you might have noticed, derived tables can make your queries extremely lengthy and difficult to read. For example, consider this complex query:

Copy
        
1 SELECT e.employee_id, e.name, e.salary, dept_avg.avg_salary, dept.name 2 FROM (SELECT department_id, AVG(salary) AS avg_salary FROM employees GROUP BY department_id) dept_avg JOIN employees e ON e.department_id = dept_avg.department_id JOIN departments dept ON e.department_id = dept.id 3 WHERE e.salary > dept_avg.avg_salary 4 ORDER BY e.salary DESC, dept.name ASC;

The above SQL code is so poorly formatted that it is hard to follow. The solution? Proper indentation to make it more organized and readable. This is where DbVisualizer comes in!

DbVisualizer is a top-rated, fully-featured, powerful database client with extensive support for over 50 databases. Its capabilities also include automatic and configurable SQL formatting.

To format your query, download DbVisualizer, install it, launch it, and paste your query into the SQL Editor:

Loading the query in DbVisualizer
Loading the query in DbVisualizer

Right-click on it, select the “Format SQL” option and then “Format Buffer:”

Formatting the query with just two clicks
Formatting the query with just two clicks

DbVisualizer will then format the query for you, making it easier to understand. We received the following query:

Copy
        
1 SELECT 2 e.employee_id, 3 e.name, 4 e.salary, 5 dept_avg.avg_salary, 6 dept.name 7 FROM 8 ( SELECT 9 department_id, 10 AVG(salary) AS avg_salary 11 FROM 12 employees 13 GROUP BY 14 department_id) dept_avg 15 JOIN 16 employees e 17 ON 18 e.department_id = dept_avg.department_id 19 JOIN 20 departments dept 21 ON 22 e.department_id = dept.id 23 WHERE 24 e.salary > dept_avg.avg_salary 25 ORDER BY 26 e.salary DESC, 27 dept.name ASC;

Much more readable, don’t you find? Try DbVisualizer with a free trial to test its large set of powerful features!

Conclusion

In this guide, you learned what the derived table SQL construct is, how it works, and how to use it. Thanks to some real-world scenarios, you also understood when to use derived tables in your queries.

As shown here, DbVisualizer simplifies the management of queries involving derived tables. This powerful database client supports various DBMS technologies and offers advanced features such as query optimization, SQL formatting, and ERD-like schema generation. Try DbVisualizer for free today!

FAQ

Are SQL derived tables supported by all major DBMS technologies?

SQL derived tables are supported by most major DBMS technologies, including MySQL, PostgreSQL, SQL Server, and Oracle. At the same time, there could be some variations in syntax and performance optimizations between DBMSs. So, always refer to the official documentation of your specific DBMS for details.

What is the difference between an SQL derived table and a subquery?

An SQL derived table is a temporary result set used within a query's FROM clause. On the contrary, a subquery is a query nested inside another query. Compared to a derived table, a subquery can appear in various clauses, such as WHERE, FROM, or SELECT. So, a subquery that specifically appears in the FROM clause acts as a derived table.

Can derived tables be stored on disk?

No, derived tables cannot be stored on disk as they are temporary, in-memory result sets created during the execution of a query. They exist only for the duration of the query and are not persisted beyond that. If you need to store the result of a derived table, you should use a regular table, a temporary table, or a materialized view.

Can a derived table use indexes?

Well, it depends. If the derived table is based on an underlying table that has indexes, those indexes can be used in the subquery to create the derived table. Otherwise, if the original or joined tables the derived table originates from do not have indexes, the derived table will not benefit from indexes. In short, the efficiency of the derived table relies on the indexing of the underlying data.

What is the difference between a regular derived table and a lateral derived table in MySQL?

In MySQL, a regular derived table is a subquery in the FROM clause that is evaluated independently of the outer query. That means it cannot reference columns from the outer query. In contrast, a lateral derived table—created by specifying the LATERAL keyword before the subquery—can reference columns from preceding tables in the same FROM clause. This allows it to depend on values from earlier JOINs, making lateral derived tables ideal for complex, dependent subqueries within a JOIN context.

Dbvis download link img
About the author
Antonello Zanini

Antonello is a software engineer, and often refers to himself as a technology bishop. His mission is to spread knowledge through writing.

The Table Icon
Sign up to receive The Table's roundup
More from the table
Title Author Tags Length Published
title

How to Deal With a Swollen SQL Transaction Log

author Antonello Zanini tags SQL SQL SERVER 7 min 2025-03-12
title

When, How, and Why to Use the Truncate SQL Statement

author Lukas Vileikis tags DbVisualizer MySQL SQL 6 min 2025-03-11
title

SQL PIVOT: How to Use a Pivot Table In SQL

author Leslie S. Gyamfi tags MySQL POSTGRESQL SQL SQL SERVER 9 min 2025-03-10
title

MySQL ALTER TABLE Statement: Definitive Guide

author Antonello Zanini tags ALTER TABLE MySQL 11 min 2025-03-06
title

A Complete Guide to the SQL CREATE INDEX Statement

author Antonello Zanini tags MySQL ORACLE POSTGRESQL SQL SQL SERVER 7 min 2025-03-05
title

A Complete Guide to the Order of Execution in SQL

author Antonello Zanini tags MySQL ORACLE POSTGRESQL SQL SQL SERVER 9 min 2025-03-03
title

MySQL NOW Function: Get the Current Date and Time

author Antonello Zanini tags DATETIME MySQL 5 min 2025-02-27
title

A Complete Guide to the MySQL CTE Mechanism

author Antonello Zanini tags MySQL 10 min 2025-02-26
title

SQL Operators: A Complete Walkthrough

author Lukas Vileikis tags DbVisualizer MySQL SQL 4 min 2025-02-25
title

How to Truncate Many Tables In SQL at Once

author Antonello Zanini tags MySQL ORACLE POSTGRESQL SQL SQL SERVER 6 min 2025-02-24

The content provided on dbvis.com/thetable, including but not limited to code and examples, is intended for educational and informational purposes only. We do not make any warranties or representations of any kind. Read more here.