Eine Temp-Table ist eine Tabelle, die nur so lange existiert wie deine Datenbanksitzung. Du füllst sie mit Zeilen, fragst sie ab wie jede andere Tabelle, und die Datenbank löscht sie automatisch, sobald du die Verbindung trennst. Die Beispiele funktionieren in PostgreSQL, MySQL, SQLite und SQL Server.
So nutzt du SQL-Temp-Tables
Du erstellst eine Temp-Table wie eine normale Tabelle, nur mit dem Schlüsselwort TEMPORARY. Meistens füllst du sie direkt aus einer Abfrage:
CREATE TEMPORARY TABLE table_name AS
SELECT ...;
SQL Server ist die Ausnahme: Ein # am Anfang des Namens macht eine Tabelle temporär, und SELECT ... INTO erstellt und füllt sie.
-- 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
Du kannst auch erst die Spalten definieren und die Zeilen später einfügen, genau wie bei einer permanenten Tabelle:
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
Wichtige Regeln
- Nur deine Sitzung sieht sie. Andere Verbindungen können sie nicht lesen, und die Datenbank löscht sie, wenn deine Sitzung endet. Nutzt deine Anwendung einen Connection-Pool, erstelle und frage die Temp-Table über dieselbe Verbindung ab.
-
Sie verdeckt eine permanente Tabelle mit demselben Namen. Sobald du eine Temp-Table namens
orderserstellst, liest jede Abfrage aufordersdie Temp-Table, bis du sie löschst. Wähle also Namen, die nicht kollidieren können. Das#-Präfix von SQL Server verhindert das. -
Doppeltes Erstellen schlägt fehl. Führst du dasselbe Skript zweimal in einer Sitzung aus, schlägt das
CREATEfehl, weil die Tabelle schon existiert. Lösche sie vorher:
DROP TABLE IF EXISTS paid_orders;
-- In MySQL, DROP TEMPORARY TABLE IF EXISTS can never drop a permanent table by mistake
-
MySQL kann eine Temp-Table nicht zweimal in einer Abfrage lesen. Ein Self-Join oder eine Unterabfrage auf dieselbe Temp-Table schlägt mit
ERROR 1137 (HY000): Can't reopen tablefehl. Leg bei Bedarf eine zweite Kopie an.
Alternative Syntax
-
CREATE TEMP TABLEist eine Kurzform, die PostgreSQL und SQLite akzeptieren. MySQL nicht. -
Globale Temp-Tables in SQL Server beginnen mit zwei Rauten,
##paid_orders. Jede Sitzung kann sie lesen, und SQL Server löscht sie, wenn die Sitzung endet, die sie erstellt hat. - Eine CTE erledigt denselben Job, wenn nur eine Abfrage die Zeilen braucht. Es wird nichts gespeichert, also musst du auch nichts löschen:
-- 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
Wann solltest du eine Temp-Table nutzen?
Nutze eine Temp-Table, wenn ein Ergebnis länger als eine Abfrage bestehen soll, aber nicht länger als deine Sitzung.
Dieselben Zeilen in mehreren Abfragen wiederverwenden
Wenn mehrere Reports von denselben gefilterten Zeilen ausgehen, etwa den Bestellungen dieses Monats oder den aktiven Projekten, speichere sie einmal und frag die Temp-Table ab, statt den Filter jedes Mal zu wiederholen.
Summen speichern, die du filtern oder wiederverwenden willst
Aggregiere einmal mit GROUP BY und speichere die Summen in einer Temp-Table. Danach kannst du sie filtern, ranken oder mit ihrem eigenen Durchschnitt vergleichen, ohne neu zu rechnen.
Eine komplexe Abfrage in Schritte aufteilen
Eine Abfrage mit mehreren Ebenen von Unterabfragen ist schwer zu lesen und zu debuggen. Bau jeden Schritt als Temp-Table, prüf ihre Zeilen und joine sie im nächsten Schritt mit deinen permanenten Tabellen.
Änderungen an einer Kopie ausprobieren
Bevor du ein UPDATE oder DELETE auf echte Daten loslässt, kopier die Tabelle in eine Temp-Table und führ es dort aus. So siehst du, was sich ändert, und das Original bleibt unberührt.
Praxisbeispiele für SQL-Temp-Tables
In SQL Server erstellst du jede dieser Temp-Tables mit SELECT ... INTO #name statt mit CREATE TEMPORARY TABLE.
Zwei Reports über die Bestellungen eines Monats
Filtere die Bestellungen aus dem Oktober einmal in eine Temp-Table und führ dann so viele Reports darauf aus, wie du willst:
-- 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
Kunden finden, die überdurchschnittlich viel ausgeben
Speichere die Summe jedes Kunden und vergleiche die Summen dann mit ihrem eigenen Durchschnitt:
-- 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
Das läuft nicht in MySQL, da MySQL customer_totals nicht zweimal in einer Abfrage lesen kann (Can't reopen table). Berechne den Durchschnitt vorher in einer separaten Abfrage.
Kunden finden, die länger nicht bestellt haben
Ermittle in einem Schritt die letzte Bestellung jedes Kunden und joine das dann mit der Kundenliste. Bei großen Tabellen beschleunigt ein Index auf der Temp-Table den 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
Prüfen, was ein DELETE entfernen würde
Du willst alte stornierte Bestellungen aufräumen? Führ das DELETE zuerst auf einer Kopie aus und schau dir an, was übrig bleibt:
-- 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
Weiterführende Artikel zu SQL-Temp-Tables
In diesem Blog:
- SQL CTE vs. Unterabfrage: wann eine CTE den Job ohne Temp-Table erledigt
- SQL CREATE TABLE Guide: Spaltentypen und Constraints, die auch für Temp-Tables gelten
- SQL JOINs mit Diagrammen: Temp-Tables mit permanenten Tabellen joinen
- SQL GROUP BY Guide: die Aggregate, die du oft in einer Temp-Table speicherst
- tempdb für mehr SQL-Server-Performance tunen: wo SQL Server seine Temp-Tables ablegt
- Sicher in einer Produktionsdatenbank arbeiten: weitere Wege, eine Änderung vorab zu testen
Offizielle Dokumentation:
- PostgreSQL: CREATE TABLE (TEMPORARY)
- MySQL: CREATE TEMPORARY TABLE Statement
- SQLite: CREATE TABLE
- SQL Server: CREATE TABLE, temporäre Tabellen
Beekeeper Studio ist eine kostenlose & quelloffene Datenbank-GUI
Das beste SQL-Abfrage- & Editor-Tool, das ich je benutzt habe. Es bietet alles, was ich zum Verwalten meiner Datenbank brauche. - ⭐⭐⭐⭐⭐ Mit
Beekeeper Studio ist schnell, intuitiv und einfach zu bedienen. Beekeeper unterstützt jede Menge Datenbanken und läuft hervorragend auf Windows, Mac und Linux.
Was Nutzer über Beekeeper Studio sagen
„Beekeeper Studio hat meinen alten SQL-Workflow komplett ersetzt. Es ist schnell, intuitiv und macht die Arbeit mit Datenbanken wieder zum Vergnügen.“
„Ich habe viele Datenbank-GUIs ausprobiert, aber Beekeeper trifft die perfekte Balance zwischen Funktionsumfang und Einfachheit. Es funktioniert einfach.“