# Dynamische Filteroptionen

Stellen Sie sich vor, Ihre Filteroptionen aktualisieren sich automatisch basierend auf Ihren tatsächlichen Daten - wie ein intelligenter Assistent, der immer die aktuellsten und relevantesten Auswahlmöglichkeiten bereitstellt, ohne dass Sie manuell Listen pflegen müssen.

## Was sind dynamische Filteroptionen?

Dynamische Filteroptionen verwenden SQL-Abfragen, um Filter automatisch mit Werten aus Ihren Daten zu befüllen, anstatt diese manuell einzugeben:

* **Automatisch aktualisiert** - Filteroptionen spiegeln immer Ihre aktuellen Daten wider
* **SQL-gesteuert** - Schreiben Sie Abfragen, um verfügbare Werte zu ermitteln
* **Anpassung an andere Filter** - Optionen können sich basierend auf anderen Filtern ändern
* **Datengetrieben** - Keine manuellen Listen mehr pflegen
* **Intelligent gefiltert** - Zeigen Sie nur relevante, verfügbare Optionen

**Beispiel aus der Praxis**: Anstatt manuell alle Abteilungsnamen einzugeben, schreibt Ihr Filter eine SQL-Abfrage wie `SELECT DISTINCT abteilung FROM mitarbeiter WHERE aktiv = true LIMIT 10000`, um automatisch alle aktiven Abteilungen als Filteroptionen zu erhalten.

## Dynamisch vs. manuell gesteuerte Filter

{% tabs %}
{% tab title="Dynamische Filter (SQL-gesteuert)" %}
**Filteroptionen werden automatisch aus Daten generiert:**

* **Immer aktuell**: Optionen spiegeln den aktuellen Datenbestand wider
* **Wartungsfrei**: Keine manuellen Updates nötig wenn sich Daten ändern
* **Intelligent**: Können sich basierend auf anderen Filterauswahlen ändern
* **Datengenau**: Zeigen nur Werte, die tatsächlich in den Daten existieren
* **Performant**: Abfragen können optimiert und gecacht werden

**Beste Anwendung für:**

* Abteilungen, die sich häufig ändern
* Status-Listen aus aktuellen Projekten
* Zeiträume basierend auf verfügbaren Daten
* Kategorien, die dynamisch sind
* Abhängige Filteroptionen (Stadt → Postleitzahl)
  {% endtab %}

{% tab title="Manuelle Filter (Eigene Liste)" %}
**Filteroptionen werden manuell eingegeben:**

* **Statisch**: Bleiben gleich bis manuell geändert
* **Wartungsintensiv**: Müssen bei Datenänderungen aktualisiert werden
* **Vorhersagbar**: Optionen ändern sich nicht unerwartet
* **Einfach**: Keine SQL-Kenntnisse erforderlich
* **Kontrolle**: Vollständige Kontrolle über verfügbare Optionen

**Beste Anwendung für:**

* Feste Kategorien (z.B. Prioritätsstufen: Hoch, Mittel, Niedrig)
* Standardisierte Werte
* Einfache, unveränderliche Listen
* Wenn SQL-Abfragen unnötig komplex wären
  {% endtab %}
  {% endtabs %}

## Wie dynamische Filter funktionieren

**Das Grundprinzip:**

1. **SQL-Abfrage schreiben** → Die erste Spalte der Ergebnisse wird zu Ihren Filteroptionen
2. **Automatische Aktualisierung** → Filter führt die Abfrage aus und lädt die aktuellen Werte
3. **Variable Integration** → Andere Filter können als `$variablenname` in der Abfrage verwendet werden
4. **Intelligente Anpassung** → Filteroptionen ändern sich basierend auf anderen Filterauswahlen

**Beispiel-Ablauf:**

* Benutzer wählt "Öffentliche Sicherheit" im Abteilungsfilter
* Status-Filter führt SQL-Abfrage aus: `WHERE abteilung = 'Öffentliche Sicherheit'`
* Status-Optionen zeigen nur relevante Werte für diese Abteilung
* Bei Abteilungsänderung aktualisieren sich die Status-Optionen automatisch

## Dynamische Filter einrichten

{% stepper %}
{% step %}
**Filter erstellen**

1. **Filter erstellen** und **"Auswahlliste"** als Eingabeoption wählen
2. **Im Bereich "Verfügbare Werte"** finden Sie zwei Optionen:
   * **"Eigene Liste"** (manuelle Eingabe)
   * **"Abfrage"** (SQL-gesteuert)
3. **"Abfrage" auswählen** für dynamische Optionen

{% hint style="info" %}
Die "Abfrage"-Option ist nur für Filter mit Auswahllisten verfügbar, nicht für Eingabefelder oder Kalender.
{% endhint %}
{% endstep %}

{% step %}
**SQL-Abfrage schreiben und testen**

1. **"Bearbeiten" klicken** um den SQL-Editor zu öffnen
2. **SQL-Abfrage schreiben**, die Optionen in der ersten Spalte zurückgibt:

```sql
-- Einfaches Beispiel: Alle aktiven Abteilungen
SELECT DISTINCT abteilungsname
FROM abteilungen
WHERE ist_aktiv = true
ORDER BY abteilungsname
LIMIT 10000;
```

3. **"Ausführen" klicken** um die Abfrage zu testen
4. **Ergebnisse in der Vorschau überprüfen**:
   * **Erste Spalte**: Wird zu Ihren Filteroptionen
   * **Zusätzliche Spalten**: Werden ignoriert, können aber zur Orientierung helfen, hier allerdings auf Duplikate achten!
   * **Keine leeren Werte**: NULL oder leere Strings werden automatisch ausgefiltert
5. **"Speichern" klicken** wenn die Abfrage korrekt ist

**Wichtige SQL-Elemente:**

```sql
-- Eindeutige Werte (Duplikate vermeiden), idealerweise nur eine Spalte (z. B. kategorie)
SELECT DISTINCT kategorie

-- Nur relevante Daten
WHERE status = 'aktiv'

-- Sortierung für bessere UX
ORDER BY abteilungsname

-- Maximale Anzahl (immer verwenden)
LIMIT 10000
```

{% endstep %}

{% step %}
**Filter speichern und testen**

1. **Filter speichern** - die SQL-Abfrage wird automatisch mit gespeichert
2. **Filter im Bericht testen**:
   * Filter öffnen → sollte die Werte aus Ihrer SQL-Abfrage zeigen
   * Andere Filter ändern → abhängige Filter sollten sich aktualisieren
   * Daten im System ändern → Filter sollten neue Optionen zeigen

{% hint style="success" %}
Ihr dynamischer Filter ist jetzt aktiv! Die Optionen aktualisieren sich automatisch basierend auf Ihren Daten und anderen Filterauswahlen.
{% endhint %}
{% endstep %}
{% endstepper %}

## Erweiterte Techniken

### Abhängige Filter erstellen

Erstellen Sie Filter, die auf andere Filter reagieren:

```sql
-- Städte basierend auf ausgewähltem Bundesland
SELECT DISTINCT city_name
FROM locations
WHERE state = $bundesland_filter -- <- dies ist der Systemname des Filters "Bundesland"
  AND population > 1000
ORDER BY city_name;
```

**Filter-Verkettung:**

1. **Bundesland-Filter** → Benutzer wählt "Bayern"
2. **Stadt-Filter** → Zeigt nur bayerische Städte
3. **Bezirk-Filter** → Zeigt nur Bezirke der gewählten Stadt

### Optimierung

Für große Datenmengen optimieren Sie Ihre Abfragen:

```sql
-- Indizierte Spalten verwenden
SELECT DISTINCT status
FROM projects
WHERE created_date >= '2024-01-01'  -- Indexed column
  AND department_id IN (1, 2, 3)    -- Indexed values
ORDER BY status
LIMIT 50;

-- Subqueries vermeiden wenn möglich
-- Statt:
SELECT DISTINCT category
FROM products
WHERE id IN (SELECT product_id FROM sales WHERE year = 2024)

-- Besser:
SELECT DISTINCT p.category
FROM products p
JOIN sales s ON p.id = s.product_id
WHERE s.year = 2024;
```

## Praktische Beispiele

### Beispiel 1: Abteilungsfilter mit aktiven Mitarbeitern

```sql
-- Zeigt nur Abteilungen, die derzeit aktive Mitarbeiter haben
SELECT DISTINCT a.abteilungsname
FROM abteilungen a
JOIN mitarbeiter m ON a.id = m.abteilungs_id
WHERE m.status = 'aktiv'
  AND m.ende_datum IS NULL
ORDER BY a.abteilungsname
LIMIT 10000;
```

### Beispiel 2: Statusfilter basierend auf Projekt und Jahr

```sql
-- Zeigt nur Status, die für das gewählte Projekt und Jahr existieren
SELECT DISTINCT projektstatus
FROM projekt_historie
WHERE projekt_typ = $projekt_typ
  AND YEAR(erstellt_datum) = $jahr
  AND projektstatus IS NOT NULL
ORDER BY 
  CASE projektstatus
    WHEN 'Geplant' THEN 1
    WHEN 'In Bearbeitung' THEN 2
    WHEN 'Abgeschlossen' THEN 3
    ELSE 4
  END
LIMIT 10000;
```

## Fehlerbehebung

### "Keine Optionen verfügbar"

**Mögliche Ursachen:**

* SQL-Abfrage gibt keine Ergebnisse zurück
* Erste Spalte enthält nur NULL-Werte

**Lösungsansätze:**

```sql
-- Debug-Version: Zeigt auch NULL-Werte
SELECT DISTINCT 
  abteilungsname,
  COUNT(*) as anzahl_datensaetze
FROM projekte
GROUP BY abteilungsname
ORDER BY abteilungsname
LIMIT 10000;

-- Explizit NULL-Werte ausschließen
SELECT DISTINCT abteilungsname
FROM projekte
WHERE abteilungsname IS NOT NULL
  AND abteilungsname != ''
  AND TRIM(abteilungsname) != ''
LIMIT 10000;
```

### "Filter aktualisiert sich nicht"

**Häufige Probleme:**

* Variablennamen stimmen nicht mit anderen Filtern überein
* SQL-Syntax-Fehler verhindert Ausführung
* Speicher-Probleme bei sehr häufigen Änderungen

**Diagnose:**

1. **SQL-Editor öffnen** → "Ausführen" klicken → Fehlermeldungen prüfen
2. **Variable Namen überprüfen** → Müssen exakt mit Filter-Systemnamen übereinstimmen
3. **Browser-Cache leeren** → Manchmal hilft ein Neuladen der Seite

### "Leistungs-Probleme"

**Für langsame Abfragen:**

```sql
-- LIMIT ist Pflicht (maximal 10.000 Zeilen)
SELECT DISTINCT kategorie
FROM grosse_tabelle
WHERE bedingungen
ORDER BY kategorie
LIMIT 10000;

-- Indizierte Spalten in WHERE nutzen
WHERE indizierte_spalte = wert
```

{% hint style="warning" %}
**Wichtig**: Dynamische Filter führen SQL-Abfragen bei jeder Verwendung aus. Achten Sie auf die Leistung bei großen Datenmengen und häufig genutzten Filtern.
{% endhint %}

## Best Practices

### SQL-Abfragen schreiben

1. **Erste Spalte ist entscheidend** - Nur die erste Spalte wird für Optionen verwendet
2. **DISTINCT verwenden** - Vermeidet doppelte Einträge in der Dropdown-Liste
3. **ORDER BY hinzufügen** - Sortiert Optionen für bessere Benutzererfahrung
4. **NULL-Werte filtern** - Leere Optionen vermeiden
5. **Leistung beachten** - Immer LIMIT 10000 verwenden (Pflicht)

### Variablen verwenden

1. **Exakte Namen verwenden** - `$filter_systemname` muss genau mit dem Filter-Systemnamen (Slug) übereinstimmen
2. **NULL-Behandlung** - Berücksichtigen Sie leere Filter: `WHERE (status = $status OR $status IS NULL)`
3. **Typen beachten** - Text-, Zahlen- und Datumsfilter haben verschiedene Formate

### Wartung und Überwachung

1. **Regelmäßig testen** - Überprüfen Sie Filter nach Datenbank-Änderungen
2. **Leistung überwachen** - Langsame Abfragen können die Benutzererfahrung beeinträchtigen (maximal 10.000 Zeilen möglich)
3. **Dokumentation** - Kommentieren Sie komplexe SQL-Abfragen für andere Bearbeiter

{% hint style="success" %}
**Profi-Tipp**: Beginnen Sie mit einfachen DISTINCT-Abfragen und erweitern Sie diese schrittweise um Variablen und Logik. Testen Sie jede Änderung sofort im SQL-Editor, bevor Sie den Filter speichern.
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.polyteia.com/berichte/filter/dynamische-filteroptionen.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
