Una tabella temporanea è una tabella che dura solo quanto la tua sessione sul database. La riempi di righe, la interroghi come qualsiasi altra tabella e il database la elimina per te quando ti disconnetti. Gli esempi funzionano in PostgreSQL, MySQL, SQLite e SQL Server.
Come usare le tabelle temporanee SQL
Crea una tabella temporanea come una tabella normale, con la parola chiave TEMPORARY. Di solito la riempi direttamente da una query:
CREATE TEMPORARY TABLE table_name AS
SELECT ...;
SQL Server fa eccezione: un # all'inizio del nome rende la tabella temporanea, e SELECT ... INTO la crea e la riempie.
-- Input: orders
-- id | customer | total | status
-- ---+----------+-------+---------
-- 1 | Maria | 120 | paid
-- 2 | Tom | 35 | refunded
-- 3 | Priya | 89 | paid
CREATE TEMPORARY TABLE paid_orders AS
SELECT id, customer, total FROM orders WHERE status = 'paid';
-- SQL Server: SELECT id, customer, total INTO #paid_orders FROM orders WHERE status = 'paid';
SELECT * FROM paid_orders; -- #paid_orders in SQL Server
-- Output:
-- id | customer | total
-- ---+----------+------
-- 1 | Maria | 120
-- 3 | Priya | 89
Puoi anche definire prima le colonne e inserire le righe dopo, come con una tabella permanente:
CREATE TEMPORARY TABLE temp_students ( -- SQL Server: CREATE TABLE #temp_students (
student_id INT PRIMARY KEY,
first_name VARCHAR(50),
last_name VARCHAR(50),
age INT
);
INSERT INTO temp_students (student_id, first_name, last_name, age)
VALUES (1, 'John', 'Doe', 20);
SELECT * FROM temp_students;
-- Output:
-- student_id | first_name | last_name | age
-- -----------+------------+-----------+----
-- 1 | John | Doe | 20
Regole da conoscere
- Solo la tua sessione può vederla. Le altre connessioni non possono leggerla, e il database la elimina quando la tua sessione termina. Se la tua applicazione usa un connection pool, crea la tabella temporanea e interrogala sulla stessa connessione.
-
Nasconde una tabella permanente con lo stesso nome. Una volta creata una tabella temporanea chiamata
orders, ogni query suorderslegge la tabella temporanea finché non la elimini, quindi scegli nomi che non possano entrare in conflitto. Il prefisso#di SQL Server evita il problema. -
Crearla due volte dà errore. Se esegui lo stesso script due volte nella stessa sessione, il
CREATEfallisce perché la tabella esiste già. Eliminala prima:
DROP TABLE IF EXISTS paid_orders;
-- In MySQL, DROP TEMPORARY TABLE IF EXISTS can never drop a permanent table by mistake
-
MySQL non può leggere una tabella temporanea due volte nella stessa query. Un self-join, o una subquery sulla stessa tabella temporanea, fallisce con
ERROR 1137 (HY000): Can't reopen table. Se ti serve, crea una seconda copia.
Sintassi alternative
-
CREATE TEMP TABLEè una forma più breve accettata da PostgreSQL e SQLite. MySQL no. -
Le tabelle temporanee globali di SQL Server iniziano con due cancelletti,
##paid_orders. Ogni sessione può leggerle, e SQL Server le elimina quando termina la sessione che le ha create. - Una CTE fa lo stesso lavoro quando le righe servono a una sola query. Non viene salvato nulla, quindi non c'è nulla da eliminare:
-- Input: the orders table above
WITH paid_orders AS (
SELECT id, customer, total FROM orders WHERE status = 'paid'
)
SELECT * FROM paid_orders;
-- Output:
-- id | customer | total
-- ---+----------+------
-- 1 | Maria | 120
-- 3 | Priya | 89
Quando usare una tabella temporanea?
Usa una tabella temporanea quando vuoi che un risultato resti disponibile per più di una query, ma non oltre la tua sessione.
Riusa le stesse righe in più query
Quando più report partono dalle stesse righe filtrate, come gli ordini di questo mese o i progetti attivi, salvale una volta e interroga la tabella temporanea invece di ripetere il filtro ogni volta.
Salva totali da filtrare o riusare
Aggrega una sola volta con GROUP BY e conserva i totali in una tabella temporanea. Potrai poi filtrarli, ordinarli in classifica o confrontarli con la loro media senza ricalcolarli.
Spezza una query complessa in passaggi
Una query con più livelli di subquery è difficile da leggere e da debuggare. Costruisci ogni passaggio come tabella temporanea, controllane le righe, poi uniscila alle tue tabelle permanenti nel passaggio successivo.
Prova le modifiche su una copia
Prima di eseguire un UPDATE o un DELETE sui dati reali, copia la tabella in una tabella temporanea ed eseguilo lì. Vedi cosa cambia, e l'originale resta intatto.
Esempi reali di tabelle temporanee SQL
In SQL Server, crea ciascuna di queste tabelle temporanee con SELECT ... INTO #name invece di CREATE TEMPORARY TABLE.
Due report sugli ordini di un mese
Filtra gli ordini di ottobre in una tabella temporanea una sola volta, poi esegui tutti i report che vuoi:
-- Input: orders
-- id | customer | order_date | total
-- ---+----------+------------+------
-- 1 | Maria | 2026-09-28 | 120
-- 2 | Tom | 2026-10-02 | 35
-- 3 | Maria | 2026-10-05 | 60
-- 4 | Priya | 2026-10-09 | 89
CREATE TEMPORARY TABLE october_orders AS
SELECT id, customer, total
FROM orders
WHERE order_date >= '2026-10-01' AND order_date < '2026-11-01';
SELECT COUNT(*) AS order_count, SUM(total) AS revenue
FROM october_orders;
-- Output:
-- order_count | revenue
-- ------------+--------
-- 3 | 184
SELECT customer, SUM(total) AS spent
FROM october_orders
GROUP BY customer
ORDER BY spent DESC;
-- Output:
-- customer | spent
-- ---------+------
-- Priya | 89
-- Maria | 60
-- Tom | 35
Trova i clienti che spendono più della media
Salva il totale di ogni cliente, poi confronta i totali con la loro media:
-- Input: orders
-- id | customer | total
-- ---+----------+------
-- 1 | Maria | 120
-- 2 | Tom | 35
-- 3 | Maria | 60
-- 4 | Priya | 89
-- 5 | Priya | 70
CREATE TEMPORARY TABLE customer_totals AS
SELECT customer, SUM(total) AS spent
FROM orders
GROUP BY customer;
SELECT customer, spent
FROM customer_totals
WHERE spent > (SELECT AVG(spent) FROM customer_totals)
ORDER BY spent DESC;
-- Output:
-- customer | spent
-- ---------+------
-- Maria | 180
-- Priya | 159
Questa non funziona in MySQL, che non può leggere customer_totals due volte nella stessa query (Can't reopen table). Calcola prima la media in una query separata.
Trova i clienti che non ordinano da tempo
Calcola l'ultimo ordine di ogni cliente in un passaggio, poi uniscilo alla lista clienti. Sulle tabelle grandi, un indice sulla tabella temporanea velocizza la join:
-- Input: customers
-- id | name
-- ---+------
-- 1 | Maria
-- 2 | Tom
-- 3 | Priya
-- Input: orders
-- id | customer_id | order_date
-- ---+-------------+-----------
-- 1 | 1 | 2026-09-30
-- 2 | 2 | 2026-05-14
-- 3 | 1 | 2026-04-02
-- Step 1: each customer's latest order
CREATE TEMPORARY TABLE last_orders AS
SELECT customer_id, MAX(order_date) AS last_order
FROM orders
GROUP BY customer_id;
-- Step 2: on big tables, index the column you'll join on
CREATE INDEX idx_last_orders ON last_orders (customer_id);
-- Step 3: customers with no order since July 1
SELECT c.name, l.last_order
FROM customers c
LEFT JOIN last_orders l ON l.customer_id = c.id
WHERE l.last_order IS NULL OR l.last_order < '2026-07-01'
ORDER BY c.name;
-- Output:
-- name | last_order
-- ------+-----------
-- Priya | NULL
-- Tom | 2026-05-14
Controlla cosa eliminerebbe un DELETE
Devi ripulire i vecchi ordini annullati? Esegui prima il DELETE su una copia e guarda cosa rimane:
-- Input: orders
-- id | customer | status | order_date
-- ---+----------+-----------+-----------
-- 1 | Maria | cancelled | 2025-11-03
-- 2 | Tom | shipped | 2025-12-19
-- 3 | Priya | cancelled | 2026-02-11
-- 4 | Maria | shipped | 2026-03-02
CREATE TEMPORARY TABLE orders_copy AS
SELECT * FROM orders;
DELETE FROM orders_copy
WHERE status = 'cancelled' AND order_date < '2026-01-01';
SELECT * FROM orders_copy;
-- Output:
-- id | customer | status | order_date
-- ---+----------+-----------+-----------
-- 2 | Tom | shipped | 2025-12-19
-- 3 | Priya | cancelled | 2026-02-11
-- 4 | Maria | shipped | 2026-03-02
-- The real table still has every row
SELECT COUNT(*) AS order_count FROM orders;
-- Output: 4
Approfondimenti sulle tabelle temporanee SQL
Su questo blog:
- Guida SQL CTE vs Subquery: quando una CTE basta senza tabella temporanea
- Guida a SQL CREATE TABLE: tipi di colonna e vincoli, validi anche per le tabelle temporanee
- Guida alle JOIN SQL con diagrammi: unire tabelle temporanee a tabelle permanenti
- Guida a SQL GROUP BY: gli aggregati che salverai spesso in una tabella temporanea
- Ottimizzare tempdb per migliori prestazioni di SQL Server: dove SQL Server conserva le sue tabelle temporanee
- Lavorare in sicurezza su un database di produzione: altri modi per testare una modifica prima di farla
Documentazione ufficiale:
- PostgreSQL: CREATE TABLE (TEMPORARY)
- MySQL: istruzione CREATE TEMPORARY TABLE
- SQLite: CREATE TABLE
- SQL Server: CREATE TABLE, tabelle temporanee
Beekeeper Studio è una GUI per database gratuita & open source
Il miglior strumento per query & editor SQL che abbia mai usato. Offre tutto ciò che mi serve per gestire il mio database. - ⭐⭐⭐⭐⭐ Mit
Beekeeper Studio è veloce, intuitivo e facile da usare. Beekeeper supporta tantissimi database e funziona alla grande su Windows, Mac e Linux.
Cosa dicono gli utenti di Beekeeper Studio
"Beekeeper Studio ha sostituito completamente il mio vecchio workflow SQL. È veloce, intuitivo e rende di nuovo piacevole lavorare con i database."
"Ho provato tante GUI per database, ma Beekeeper trova l'equilibrio perfetto tra funzionalità e semplicità. Funziona e basta."