Temporary Tables and Common Table Expressions (CTEs)
Introduction
Temporary tables and Common Table Expressions (CTEs) are useful for breaking down complex queries and storing intermediate results. This section will cover how to create and use temporary tables and CTEs in SQL, including MySQL, PostgreSQL, SQL Server, and DuckDB.
Temporary Tables
What are Temporary Tables?
Temporary tables are tables that exist temporarily during the session or until the query that created them ends. They are useful for storing intermediate results that need further processing.
Creating Temporary Tables
The syntax for creating a temporary table varies slightly between SQL dialects.
MySQL
CREATE TEMPORARY TABLE temp_table_name (
column1 datatype,
column2 datatype,
...
);
PostgreSQL
CREATE TEMP TABLE temp_table_name (
column1 datatype,
column2 datatype,
...
);
SQL Server
CREATE TABLE #temp_table_name (
column1 datatype,
column2 datatype,
...
);
DuckDB
CREATE TEMP TABLE temp_table_name (
column1 datatype,
column2 datatype,
...
);
Example
Create a temporary table to store intermediate results:
CREATE TEMP TABLE temp_sales (
product_id INT,
total_sales DECIMAL(10, 2)
);
INSERT INTO temp_sales (product_id, total_sales)
SELECT
productid,
SUM(amount)
FROM sales
GROUP BY product_id;
SELECT * FROM temp_sales;
Dropping Temporary Tables
Temporary tables are automatically dropped at the end of the session. However, you can explicitly drop them.
DROP TABLE temp_sales;
Common Table Expressions (CTEs)
What are CTEs?
CTEs are temporary result sets that are defined within the execution scope of a single SELECT
, INSERT
, UPDATE
, or DELETE
statement. They make queries easier to read and maintain by breaking down complex queries.
Creating CTEs
CTEs are created using the WIT
H keyword followed by the CTE
name and the query that defines it.
WITH cte_name AS (
SELECT column1, column2, ...
FROM table_name
WHERE condition
)
SELECT column1, column2, ...
FROM cte_name;
Example
Using a CTE
to calculate total sales and then retrieve products with sales greater than 1000:
WITH TotalSales AS (
SELECT productid, SUM(amount) AS total_sales
FROM sales
GROUP BY productid
)
SELECT productid, total_sales
FROM TotalSales
WHERE total_sales > 1000;
Recursive CTEs
Recursive CTEs are useful for hierarchical or recursive data structures such as organizational charts or tree structures.
WITH RECURSIVE cte_name AS (
-- Anchor member
SELECT column1, column2, ...
FROM table_name
WHERE condition
UNION ALL
-- Recursive member
SELECT column1, column2, ...
FROM table_name
INNER JOIN cte_name ON table_name.column = cte_name.column
)
SELECT column1, column2, ...
FROM cte_name;
Example
Using a recursive CTE
to retrieve an employee hierarchy:
WITH RECURSIVE EmployeeHierarchy AS (
SELECT employeeid, managerid, firstname, lastname
FROM employees
WHERE manager_id IS NULL
UNION ALL
SELECT e.employeeid, e.managerid, e.firstname, e.lastname
FROM employees e
INNER JOIN EmployeeHierarchy eh ON e.manager_id = eh.employee_id
)
SELECT employeeid, firstname, lastname, managerid
FROM EmployeeHierarchy;
Practice Exercises
- Create a
CTE
containting allemployee
that work inmarketing
, use this in your select statement to get thefirstname
andlastname
of these employees. - create a
temp
table with thesum
of allsales
, how query this table working out how much this would be if50%
of thetotal sales
was added oon.