This lesson on Temp Tables is hands-on and example-driven. You will create, populate, and manage session-scoped SQL temporary tables using the hash prefix syntax. You will optimize analytical workflows by staging intermediate query results and pre-calculated aggregations, cutting query runtimes and preventing repetitive multi-table joins.
What You'll Be Able To Do
- Create session-scoped temporary tables using explicit schema definitions and the
#prefix. - Insert single records and multi-row query subsets into temporary tables.
- Stage complex join and aggregation outputs into temporary tables for multi-query reuse.
- Implement
DROP TABLE IF EXISTSguards to prevent object collision errors during script reruns.
Detailed Concept Walkthrough
1. Temporary Table Creation and Syntax
Temporary tables are physically materialized tables that exist exclusively within the lifetime of an active database connection. They share standard table DDL syntax except for a leading hash prefix.
- Mechanism: Create a temp table using
CREATE TABLE #tablenamefollowed by standard column specifications. The#prefix informs the database engine to isolate the table to the current session. - Under the Hood: Unlike persistent user tables, temporary tables are allocated in system temporary storage (such as
tempdb) and automatically purge when the user session disconnects. - Syntax Rule: Column definitions must adhere to standard SQL data types, such as
INTandVARCHAR(n), matching the data structures intended for staging.
-- Create a session-scoped temporary table
CREATE TABLE #temp_employee (
EmployeeID INT,
JobTitle VARCHAR(100),
Salary INT
);
Key Takeaway: A single
#prefix marks a table as temporary and isolates it to your active database session.
2. Populating and Staging Query Subsets
Temp tables can ingest individual row values or capture entire subsets directly from base tables using insert-select statements.
- Mechanism: Populate tables manually using
INSERT INTO #table VALUES (...)or programmatically pipe query results usingINSERT INTO #table SELECT .... - Under the Hood: When populating via
SELECT, the database engine materializes the query result set into temporary storage, decoupling subsequent operations from the source tables. - Best Practice: Use
INSERT INTO #table SELECTto isolate smaller working subsets from massive billion-row base tables before running downstream analytics.
-- Insert an explicit single row
INSERT INTO #temp_employee VALUES (101, 'HR', 45000);
-- Stage a subset from a large base table
INSERT INTO #temp_employee
SELECT EmployeeID, JobTitle, Salary
FROM EmployeeSalary;
Key Takeaway: Staging data from large tables into temporary tables decouples analytics from expensive source table scans.
3. Intermediate Aggregations and Performance Optimization
Persisting complex multi-table joins and aggregations into temp tables prevents redundant computation across multiple downstream analytical queries.
- Mechanism: Compute resource-intensive joins and
GROUP BYaggregations once, writing the output directly into a dedicated temp table. - Under the Hood: Unlike CTEs and subqueries that re-execute their underlying logic each time they are referenced, temp tables store materialized results on disk/memory for fast, repeated querying.
- Best Practice: Target multi-table joins with grouping functions for temporary materialization whenever downstream tasks require filtering or slicing the same aggregate metrics.
-- Define temp table for aggregated metrics
CREATE TABLE #temp_Employee2 (
JobTitle VARCHAR(50),
EmployeesPerJob INT,
AvgAge INT,
AvgSalary INT
);
-- Stage complex join and aggregation results
INSERT INTO #temp_Employee2
SELECT JobTitle, COUNT(JobTitle), AVG(Age), AVG(Salary)
FROM EmployeeDemographics emp
JOIN EmployeeSalary sal ON emp.EmployeeID = sal.EmployeeID
GROUP BY JobTitle;
-- Query materialized metrics without re-joining
SELECT * FROM #temp_Employee2 WHERE AvgSalary > 50000;
Key Takeaway: Temp tables materialize expensive joins and aggregations once, allowing fast repeated querying without re-executing calculations.
4. Idempotent Execution and Stored Procedures
Because temp tables persist until a session closes, re-executing creation scripts will fail unless existing objects are conditionally dropped first.
- Mechanism: Place
DROP TABLE IF EXISTS #tablenameprior toCREATE TABLEstatements to eliminate collision errors when scripts run repeatedly. - Under the Hood: If a temp table exists in the connection scope, attempting a new
CREATE TABLEthrows an object-already-exists error because the metadata entry is still active. - Best Practice: Always guard temp table definitions with conditional drop statements inside stored procedures and iterative development scripts to guarantee idempotency.
-- Ensure script rerunability by dropping prior instances
DROP TABLE IF EXISTS #temp_Employee2;
CREATE TABLE #temp_Employee2 (
JobTitle VARCHAR(50),
EmployeesPerJob INT,
AvgAge INT,
AvgSalary INT
);
Key Takeaway: Guarding creation statements with
DROP TABLE IF EXISTSensures stored procedures and scripts execute idempotently.
Topics Covered in Temp Tables
- Temp Tables Overview (0:00 - 0:35) — Temp tables are introduced as session-bound storage structures that allow multiple downstream reads unlike single-use CTEs.
- Creating and Inserting Data (0:35 - 1:25) — The hash prefix syntax is introduced alongside basic DDL and row-level value insertion techniques.
- Staging Subsets from Large Tables (1:25 - 2:15) — Query results are inserted directly into temp tables to avoid repeated full table scans on large datasets.
- Aggregations and Downstream Reuse (2:15 - 3:40) — A complex multi-table join with group by aggregations is staged to show processing time reductions.
- DROP TABLE and Idempotency (3:40 - 4:45) — Conditional drop table syntax is implemented to prevent execution errors during repeated stored procedure runs.
SQL Cheat Sheet
-
CREATE TABLE #table_name (...)— Creates a session-scoped temporary table schemaCREATE TABLE #temp_employee (EmployeeID INT, JobTitle VARCHAR(100), Salary INT); -
INSERT INTO #table_name VALUES (...)— Inserts explicit row values into a temporary tableINSERT INTO #temp_employee VALUES (101, 'HR', 45000); -
INSERT INTO #table_name SELECT ...— Populates a temp table with query resultsINSERT INTO #temp_employee SELECT EmployeeID, JobTitle, Salary FROM EmployeeSalary; -
SELECT ... FROM #table_name— Reads stored data from an active temporary tableSELECT JobTitle, AvgSalary FROM #temp_Employee2 WHERE EmployeesPerJob > 5; -
DROP TABLE IF EXISTS #table_name— Deletes temporary table if it already existsDROP TABLE IF EXISTS #temp_Employee2;
Comparison Table
| Aspect | Temporary Table (#temp) | CTE / Subquery |
|---|---|---|
| Reusability | Queried multiple times across a session | Evaluated once per statement |
| Storage | Materialized in temporary storage | In-memory during single execution |
| Performance Impact | Calculates once; reduces repeat join overhead | Recomputes underlying logic every reference |
| Script Idempotency | Requires DROP TABLE handling on reruns | No object cleanup required |
Common Pitfalls
- Mistake: Rerunning creation scripts without dropping previous instances causes table already exists errors. Avoid: Prepend every temp table creation with DROP TABLE IF EXISTS.
- Mistake: Using CTEs when repeatedly referencing an expensive multi-table join. Avoid: Stage intermediate join results into a temporary table once.
- Mistake: Omitting the hash prefix when defining temporary tables. Avoid: Always prefix session table names with a pound sign like #temp_table.
- Mistake: Expecting temporary tables to persist after disconnecting the session. Avoid: Treat temporary tables as connection-bound scratchpads and write permanent data to base tables.
FAQs
- What is the primary difference between a CTE and a temporary table? A CTE is scoped strictly to a single statement and recalculates upon every reference, whereas a temporary table materializes data across multiple queries within a session.
- Why should I stage data into a temp table instead of querying base tables directly? Staging filtered subsets or pre-aggregated joins eliminates the processing overhead of repeatedly scanning billion-row tables and executing complex joins.
- Where do temporary tables live inside the database? Temporary tables are stored in temporary system storage (such as tempdb in SQL Server) rather than within the permanent database schema.
- Why does running my stored procedure a second time throw a collision error?
The temporary table created during the first run remains in the active session; adding
DROP TABLE IF EXISTSresolves the collision.