# SQL-Variablen

Denken Sie an Lücken in einem Serienbrief - Sie schreiben den Brief einmal mit Platzhaltern für "Name" und "Abteilung", dann können Sie jedes Mal, wenn Sie ihn verwenden, verschiedene Werte einsetzen. SQL-Variablen ermöglichen es Ihnen, eine Abfrage zu schreiben, die verschiedene Ergebnisse basierend auf den Werten zeigt, die Sie bereitstellen.

## Was SQL-Variablen sind

SQL-Variablen sind Platzhalter in Ihren SQL-Abfragen, die es Ihnen ermöglichen:

* **Flexible Abfragen zu erstellen** - Einmal schreiben, mit verschiedenen Werten verwenden
* **Verschiedene Szenarien zu testen** - Verschiedene Werte ausprobieren, ohne SQL umzuschreiben
* **Dynamische Berichte zu erstellen** - Dieselbe Abfrage zeigt verschiedene Daten basierend auf der Benutzerauswahl
* **Mit Berichtsfiltern zu verbinden** - Variablen werden zu benutzerfreundlichen Filtern in Berichten

**Beispiel aus der Praxis**: Anstatt separate Abfragen für jede Abteilung zu schreiben, schreiben Sie eine Abfrage mit `$abteilung` und testen sie dann mit "Öffentliche Sicherheit", "Gesundheitsdienste" oder jedem anderen Abteilungsnamen.

## Variablen-Syntax

Variablen verwenden eine einfache Dollar-Zeichen-Syntax in Ihren SQL-Abfragen.

```sql
SELECT abteilung, status, budget, erstellungsdatum
FROM projekte 
WHERE abteilung = $abteilungsfilter
  AND status = $projektstatus
  AND budget >= $mindestbudget
  AND erstellungsdatum >= $startdatum
```

{% hint style="info" %}
**Hinweis:** Derzeit können Variablen nur in WHERE-Klauseln verwendet werden.
{% endhint %}

**Regeln für Variablennamen:**

* **Muss mit Buchstabe oder Unterstrich beginnen**: `$abteilung` ✅, `$_filter` ✅
* **Kann Buchstaben, Zahlen, Unterstriche enthalten**: `$region_2024` ✅, `$statusfilter` ✅
* **Kann nicht mit Zahlen beginnen**: `$2024_daten` ❌
* **Kann keine Leerzeichen oder Sonderzeichen enthalten**: `$mein-filter` ❌, `$mein filter` ❌

**Aktuelle Einschränkungen:**

* **Nur WHERE-Klausel**: Variablen können nur in WHERE-Bedingungen verwendet werden
* **Keine Spaltennamen**: Variablen können nicht für SELECT-Spalten wie `SELECT $spaltenname FROM tabelle` verwendet werden
* **Kein GROUP BY/ORDER BY**: Variablen können nicht in `GROUP BY $gruppenfeld` oder `ORDER BY $sortierfeld` verwendet werden

Für vollständige technische Details siehe [DuckDBs Dokumentation zu benannten Parametern](https://duckdb.org/docs/stable/sql/query_syntax/prepared_statements.html#named-parameters-parameter).

{% hint style="info" %}
Verwenden Sie beschreibende Namen wie `$abteilungsfilter` oder `$startdatum` anstatt generische Namen wie `$var1` oder `$x`. Dies macht Ihre Abfragen später leichter verständlich.
{% endhint %}

## Wie Variablen in der Benutzeroberfläche funktionieren

Wenn Sie eine SQL-Abfrage mit Variablen schreiben, erkennt das System sie automatisch und erstellt interaktive Steuerelemente über der Tabellenvorschau oder Diagrammvorschau auf der linken Seite der Benutzeroberfläche.

### Variablen steuern

Jede Variable bekommt ihre eigene kleine Steuerung, in der Ihnen folgende Funktionen zur Verfügung stehen:

{% stepper %}
{% step %}
**Mit verschiedenen Variablentypen testen**

Sie können Ihre Variablen mit verschiedenen Datentypen testen:

* **Text** - Für Namen, Kategorien, Beschreibungen
* **Zahl** - Für Beträge, Anzahlen, IDs
* **Datum** - Für zeitbasierte Filterung (YYYY-MM-DD-Format)

Die Benutzeroberfläche ermöglicht es Ihnen zu testen, wie sich Ihre Abfrage mit verschiedenen Arten von Werten verhält.
{% endstep %}

{% step %}
**Einzelne oder mehrere Werte wählen**

**Einzelwert-Modus:**

* Geben Sie einen Wert ein, der die Variable ersetzt
* Beispiel: `$abteilung` wird zu `"Öffentliche Sicherheit"`

**Mehrwert-Modus:**

* Geben Sie mehrere Werte getrennt durch Semikolons ein
* Beispiel: `$statusliste` wird zu `"Aktiv; Ausstehend; Überprüfung"`
* Verwenden Sie mit `IN`-Klausel: `WHERE status IN ($statusliste)`
  {% endstep %}

{% step %}
**Ihre Testwerte eingeben**

**Für Textwerte:**

* Direkt tippen: `Öffentliche Sicherheit`
* Mehrere Werte: `Aktiv; Ausstehend; Abgeschlossen`
* Semikolons wörtlich einschließen: `Text mit \; Semikolon`

**Für Zahlen:**

* Einzeln: `1000`
* Mehrere: `100; 500; 1000`

**Für Daten:**

* Immer YYYY-MM-DD-Format verwenden: `2024-01-15`
* Nur einzelnes Datum (keine mehreren Datumswerte)
  {% endstep %}

{% step %}
**Ihre Abfrage testen**

Klicken Sie **"Anwenden"** auf der Variablen-Pill, um mit diesen Werten zu testen, dann führen Sie Ihre Abfrage aus, um die Ergebnisse zu sehen.
{% endstep %}
{% endstepper %}

## Häufige Variablenmuster

### Einzelwert-Filterung

```sql
SELECT abteilung, COUNT(*) as mitarbeiteranzahl
FROM mitarbeiter 
WHERE abteilung = $abteilung
GROUP BY abteilung
ORDER BY mitarbeiteranzahl DESC
```

**Variablen-Setup:**

* Name: `abteilung`
* Testen mit: Textwerten wie `Öffentliche Sicherheit`
* Modus: Einzelwert

### Mehrwert-Filterung

```sql
SELECT * 
FROM projekte
WHERE status IN $statusliste
  AND prioritaet IN $prioritaetsliste
ORDER BY erstellungsdatum DESC
```

**Variablen-Setup:**

* Name: `statusliste`
* Testen mit: Mehreren Textwerten wie `Aktiv; Überprüfung; Planung`
* Modus: Mehrere Werte

### Datumsbereichs-Filterung

```sql
SELECT * 
FROM budgetposten
WHERE erstellungsdatum >= $startdatum 
  AND erstellungsdatum <= $enddatum
  AND betrag >= $mindestbetrag
ORDER BY erstellungsdatum
```

**Variablen-Setup:**

* `startdatum`: Testen mit Datumswerten wie `2024-01-01`
* `enddatum`: Testen mit Datumswerten wie `2024-12-31`
* `mindestbetrag`: Testen mit Zahlenwerten wie `1000`

### Umgang mit leeren Variablen

Wenn kein Filter angewendet werden soll, verwenden Sie dieses Muster, um alle Daten zu zeigen:

```sql
SELECT * 
FROM projekte
WHERE (abteilung = $abteilung OR $abteilung IS NULL)
  AND (status IN $statusliste OR array_length($statusliste) = 0)
```

Dies gewährleistet:

* Wenn Sie `$abteilung` auf "Öffentliche Sicherheit" setzen, zeigen nur diese Projekte
* Wenn Sie `$abteilung` leer lassen, zeigen ALLE Abteilungen
* Dieselbe Logik funktioniert für die Statusliste

**Wichtiger Unterschied für Mehrfachauswahl-Variablen:**

* **Einzelwert-Variablen** verwenden `OR $variable IS NULL` wenn leer
* **Mehrfachauswahl-Variablen** verwenden `OR array_length($variable) = 0` wenn keine Optionen ausgewählt sind

Mehrfachauswahl-Filter senden leere Arrays (nicht Null-Werte) wenn keine Auswahl im Filter getroffen wurde (leere Auswahl). Die `array_length()`-Funktion gibt 0 für leere Arrays zurück, wodurch Ihre Abfrage alle Daten anzeigen kann, wenn keine Filteroptionen ausgewählt sind.

{% hint style="success" %}
**Profi-Tipp**: Schließen Sie immer das richtige Muster für leere Filter ein:

* Einzelwert-Variablen: `OR $variable IS NULL`
* Mehrfachauswahl-Variablen: `OR array_length($variable) = 0`

Dies macht Ihre Abfragen funktionsfähig, egal ob Filter gesetzt sind oder nicht, was besonders wichtig ist, wenn Sie Variablen in Berichten verwenden.
{% endhint %}

## Variablen in Auswertungen testen

Variablen sind perfekt zum Testen verschiedener Szenarien beim Erstellen von Auswertungen:

### Entwicklungsworkflow

{% stepper %}
{% step %}
**Schreiben Sie Ihre Basis-Abfrage**

Beginnen Sie mit einer Abfrage, die ohne Variablen funktioniert:

```sql
SELECT abteilung, AVG(budget) as durchschnittsbudget
FROM projekte 
WHERE status = 'Aktiv'
GROUP BY abteilung
```

{% endstep %}

{% step %}
**Fügen Sie Variablen für Flexibilität hinzu**

Ersetzen Sie feste Werte durch Variablen:

```sql
SELECT abteilung, AVG(budget) as durchschnittsbudget
FROM projekte 
WHERE (status IN $statusfilter OR array_length($statusfilter) = 0)
  AND (abteilung = $abteilungsfilter OR $abteilungsfilter IS NULL)
GROUP BY abteilung
```

{% endstep %}

{% step %}
**Verschiedene Szenarien testen**

Verwenden Sie die Variablen-Pills zum Testen:

* Alle aktiven Projekte: `statusfilter` = `Aktiv`
* Aktiv und ausstehend: `statusfilter` = `Aktiv; Ausstehend`
* Spezifische Abteilung: `abteilungsfilter` = `Gesundheitsdienste`
* Alle Abteilungen: `abteilungsfilter` leer lassen
  {% endstep %}

{% step %}
**Verifizieren Sie, dass Ergebnisse Sinn machen**

Überprüfen Sie, dass Ihre Abfrage erwartete Ergebnisse für jeden Testfall zurückgibt, bevor Sie sie in Berichten verwenden.
{% endstep %}
{% endstepper %}

## Von Variablen in Auswertungen zu Berichtsfiltern

Die wahre Macht von Variablen zeigt sich, wenn Sie Auswertungen mit Variablen in Berichten verwenden:

### Die Verbindung

1. **In Auswertungen**: Variablen ermöglichen es Ihnen, verschiedene Abfrageparameter zu testen
2. **In Berichten**: Dieselben Variablen können zu benutzerfreundlichen Filtern werden
3. **Für Endnutzer des Berichts**: Sie sehen Menüs und Datumsauswähler, nicht rohen SQL-Code

### Beispiel-Transformation

**Ihre SQL-Auswertung mit Variablen:**

```sql
SELECT abteilung, COUNT(*) as projektanzahl
FROM projekte
WHERE (status IN $projektstatus OR array_length($projektstatus) = 0)
  AND (erstellungsdatum >= $startdatum OR $startdatum IS NULL)
```

**Wird zu diesem für Berichtsbenutzer:**

* **Projektstatus**-Filter mit Auswahl: "Aktiv", "Ausstehend", "Abgeschlossen"
* **Startdatum**-Filter für die Auswahl des frühesten einzuschließenden Datums

### Warum das wichtig ist

* **Entwickler** arbeiten mit flexiblen SQL-Abfragen mit Variablen
* **Berichts-Ersteller** verbinden Variablen mit benutzerfreundlichen Filter-Benutzeroberflächen
* **Endnutzer** bekommen intuitive Steuerelemente, ohne SQL-Code zu sehen oder zu bearbeiten

Für vollständige Details zur Verbindung von Variablen mit Berichtsfiltern siehe [**Berichtsfilter**](https://docs.polyteia.com/berichte/filter).

## Tipps

### Variablennamen

* **Seien Sie beschreibend**: `$abteilungsfilter` nicht `$a`
* **Seien Sie konsistent**: Wenn Sie das `_filter`-Suffix verwenden, verwenden Sie es überall
* **Passen Sie zu Ihren Daten**: Verwenden Sie Namen, die zu Ihren Spaltennamen passen, wenn möglich

### Abfrage-Design

* **Behandeln Sie Nulls ordnungsgemäß**: Schließen Sie immer `OR $variable IS NULL` für optionale Filter ein
* **Testen Sie gründlich**: Probieren Sie leere Werte, Einzelwerte und mehrere Werte
* **Verwenden Sie angemessene SQL-Klauseln**: `=` für Einzelwerte, `IN` für Listen

### Variablentypen

* **Text**: Für Kategorien, Namen, Beschreibungen
* **Zahl**: Für Beträge, Anzahlen, IDs
* **Datum**: Nur für Datumswerte, immer YYYY-MM-DD-Format

### Test-Ablauf

1. **Beginnen Sie einfach**: Testen Sie zuerst mit Einzelwerten
2. **Fügen Sie Komplexität hinzu**: Probieren Sie mehrere Werte und Kombinationen
3. **Testen Sie Grenzfälle**: Leere Werte, alle Werte, keine Treffer
4. **Verifizieren Sie Logik**: Stellen Sie sicher, dass NULL-Behandlung korrekt funktioniert

{% hint style="warning" %}
**Denken Sie daran**: Variablen sind abhängig von Groß- und Kleinschreibung. `$Abteilung` und `$abteilung` sind verschiedene Variablen. Bleiben Sie bei Kleinschreibung mit Unterstrichen für Konsistenz.
{% endhint %}

## Häufige Problembehandlung

### Variable nicht erkannt

**Problem**: Sie haben `$abteilung` getippt, aber sehen keine Variable wird erkannt

**Lösung**: Überprüfen Sie die Rechtschreibung und stellen Sie sicher, dass der Variablenname den Namensregeln folgt

### Abfrage schlägt mit Variablen fehl

**Problem**: Abfrage funktioniert ohne Variablen, aber schlägt fehl, wenn Sie sie hinzufügen

**Lösung**: Überprüfen Sie Ihre NULL-Behandlung - fügen Sie `OR $variable IS NULL`-Bedingungen hinzu

### Falscher Datentyp

**Problem**: Ihre Datumsvariable zeigt Textwerte oder Zahlen werden als Text angezeigt

**Lösung**: Testen Sie mit dem korrekten Datentyp in der Variablen-Benutzeroberfläche - probieren Sie Datumsformat YYYY-MM-DD für Daten

### Mehrere Werte funktionieren nicht

**Problem**: Mehrere Werte in einer Variable filtern nicht korrekt

**Lösung**: Stellen Sie sicher, dass Sie `IN ($variable)` und nicht `= $variable` für Listen verwenden

## Erweiterte Muster

### Komplexe Filterung

```sql
SELECT * 
FROM projekte
WHERE 
  -- Datumsbereichs-Filterung
  (erstellungsdatum BETWEEN $startdatum AND $enddatum 
   OR ($startdatum IS NULL AND $enddatum IS NULL))
  
  -- Multi-Kriterien-Filterung  
  AND (
    (abteilung IN $abteilungsliste OR array_length($abteilungsliste) = 0)
    AND (status IN $statusliste OR array_length($statusliste) = 0)
    AND (budget >= $mindestbudget OR $mindestbudget IS NULL)
  )
```

{% hint style="info" %}
**Denken Sie daran**: Variablen können nur in WHERE-Klauseln verwendet werden. Komplexe Logik mit CASE-Anweisungen, dynamische Spaltenauswahl oder variable GROUP BY/ORDER BY-Klauseln werden derzeit nicht unterstützt.
{% endhint %}

Bereit, Variablen in Berichten zu verwenden? Erfahren Sie, wie Sie Ihre SQL-Auswertungen mit benutzerfreundlichen Berichtsfiltern in der [**Berichtsfilter-Dokumentation**](https://docs.polyteia.com/berichte/filter) verbinden.
