MWCodebymw.de ↗
SQL

CREATE VIEW – die Abfrage, die du nur einmal schreibst

Wenn dieselbe 15-zeilige Abfrage an vier Stellen im Code steht, ändert man sie irgendwann an dreien. Eine View gibt ihr einen Namen – danach steht sie nur noch an einer Stelle.

Es gibt in jedem Projekt diese eine Abfrage, die überall gebraucht wird. Bei mir sieht sie ungefähr so aus:

SELECT r.id, r.nummer, r.betrag_cent, r.faellig_am, k.name AS kunde
FROM rechnungen r
JOIN kunden k ON k.id = r.kunde_id
WHERE r.storniert = 0
  AND NOT EXISTS (SELECT 1 FROM zahlungen z WHERE z.rechnung_id = r.id)

„Offene Rechnungen". Die steht dann im Dashboard, im Export, in der Mahnungsliste und im Monatsbericht — vier Kopien. Und wenn irgendwann Teilzahlungen dazukommen, ändert man sie an dreien.

Gib ihr einen Namen

CREATE VIEW offene_rechnungen AS
SELECT r.id, r.nummer, r.betrag_cent, r.faellig_am, k.name AS kunde
FROM rechnungen r
JOIN kunden k ON k.id = r.kunde_id
WHERE r.storniert = 0
  AND NOT EXISTS (SELECT 1 FROM zahlungen z WHERE z.rechnung_id = r.id);

Ab jetzt ist das eine Tabelle — jedenfalls fühlt es sich so an:

SELECT * FROM offene_rechnungen ORDER BY faellig_am;

SELECT kunde, SUM(betrag_cent) AS summe
FROM offene_rechnungen
GROUP BY kunde
ORDER BY summe DESC;

SELECT COUNT(*) FROM offene_rechnungen WHERE faellig_am < date('now');

Drei völlig verschiedene Auswertungen, und die Definition von „offen" steht genau einmal in der Datenbank.

Was eine View ist – und was nicht

Eine View speichert keine Daten. Sie ist ein gespeicherter Name für eine Abfrage. Jedes Mal, wenn du sie benutzt, führt die Datenbank die dahinterliegende Abfrage aus. Das heißt:

  • Sie ist immer aktuell — es gibt nichts, das veralten könnte.
  • Sie ist nicht schneller. Wenn die zugrundeliegende Abfrage langsam ist, ist die View es auch. Der Gewinn liegt in der Wartbarkeit, nicht in der Geschwindigkeit.

In SQLite sind Views außerdem schreibgeschützt: INSERT INTO offene_rechnungen … geht nicht. Das ist meist genau richtig — eine View ist zum Auswerten da.

Wo sie mir am meisten hilft

Nicht beim Sparen von Tipparbeit, sondern beim Festhalten einer Definition. „Offen", „aktiv", „diesen Monat", „hat gekündigt" — das sind fachliche Begriffe, über die man mit Kunden spricht. Wenn sie an vier Stellen leicht unterschiedlich implementiert sind, kommen im Dashboard und im Bericht verschiedene Zahlen heraus. Und dann diskutiert man eine Stunde über eine Zahl, statt über das Geschäft.

Eine View macht daraus eine einzige, nachlesbare Wahrheit.

Ändern und aufräumen

Es gibt kein ALTER VIEW. Man wirft sie weg und legt sie neu an:

DROP VIEW IF EXISTS offene_rechnungen;
CREATE VIEW offene_rechnungen AS …;

Das gehört bei mir in dieselbe Schema-Migration wie Tabellenänderungen — sonst zeigt die View nach einer Spaltenumbenennung ins Leere, und der Fehler taucht erst auf, wenn jemand den Monatsbericht öffnet.

Und wenn ich Parameter brauche?

Views nehmen keine Parameter. Wenn du „offene Rechnungen eines Kunden" willst, filterst du außen:

SELECT * FROM offene_rechnungen WHERE kunde = ?;

Das ist völlig ausreichend — die Datenbank zieht die Bedingung beim Ausführen in die Abfrage hinein.

Du hast ein Projekt, in dem dieselbe Auswertung an mehreren Stellen leicht unterschiedliche Zahlen liefert? Das ist ein klassisches Symptom. Schreib mir.

Quellen

#SQL#VIEW#SQLite#Wartbarkeit#Abfragen

Du brauchst mehr als ein Snippet?

Ich entwickle Android-Apps in Kotlin und moderne Websites für Selbstständige und kleine Unternehmen — von der ersten Idee bis zum Release.

Projekt anfragen →