Data-Grid-Berichte

Zuletzt aktualisiert 25 May 2026

Ein Flexie-Data-Grid-Bericht mit einer Abfrage, Nutzerfiltern und der resultierenden sortierbaren, paginierten Tabelle

Sie schreiben eine SELECT-Abfrage. Flexie führt sie aus, wendet darauf alle vom Nutzer gesetzten Filter und Sortierungen an und zeigt das Ergebnis als paginierte Tabelle mit anklickbaren Spaltenköpfen zum Sortieren. Der Nutzer kann Filter ändern, die Sortierung ändern, die Seitengröße anpassen und das vollständige Ergebnis als CSV exportieren.

Das ist die richtige Wahl für jeden Bericht, dessen Ausgabe aus Zeilen und Spalten besteht: eine Liste überfälliger Rechnungen, die besten Kunden nach Lifetime-Value, die Aktivität der Bearbeiter und so weiter. Starten Sie bei Reports (/reports), klicken Sie auf New und setzen Sie das Ausgabeformat auf Data Grid.

Der Aufbau eines Data-Grid-Berichts

QUERY SELECT name, amount, stage_id FROM deals WHERE is_won = 1 {filters} ORDER BY amount DESC NUTZERFILTER Status ▾ Von / Bis Inhaber ▾ Deal-Name ▾ Betrag Phase Acme Verlängerung €12,400 Gewonnen Contoso Upgrade €8,200 Gewonnen Northwind Add-on €5,750 Gewonnen Fabrikam Q3 €4,100 Gewonnen CSV exportieren 1 bis 4 von 432 ‹ 1 2 3 ›

Die Berichtseinstellungen

Einstellung Zweck
Name Erforderlich. Wird in der Berichtsliste, auf der Ansichtsseite des Berichts und in jedem Dashboard-Widget angezeigt, das ihn verwendet.
Beschreibung Optionale Notizen, die auf der Ansichtsseite erscheinen.
Kategorie Optionaler Ordner zur Gruppierung von Berichten.
Ausgabeformat Data Grid (das Thema dieser Seite).
Abfrage Die SELECT-Anweisung. Erforderlich. Das größte Feld im Formular.
Filter (JSON) Optionale Nutzereingabe-Filter, die über dem Bericht angezeigt werden (siehe unten).
Standard-Sortierspalte Nach welcher Spalte das Ergebnis beim ersten Öffnen sortiert wird.
Standard-Sortierrichtung Ascending oder Descending.
Wer darf auf diesen Bericht zugreifen? Wer diesen Bericht öffnen darf. Kombinationen aus Alle Nutzer, bestimmten Rollen, Nutzergruppen oder einzelnen Nutzern. Siehe Zugriffssteuerung.

Die Abfrage schreiben

Der Inhalt eines Data-Grid-Berichts ist eine einzige SELECT-Anweisung.

Einfaches Beispiel

SELECT id, name, owner_id, amount, stage_id, date_added
FROM deals
WHERE is_won = 1
ORDER BY amount DESC

Das ist ein vollständiger, funktionierender Bericht. Speichern Sie ihn und öffnen Sie die Ansichtsseite.

Joins und Aggregationen

JOINs, GROUP BY, Aggregatfunktionen, alles, was SELECT unterstützt, ist erlaubt:

SELECT u.full_name, COUNT(d.id) AS deal_count, SUM(d.amount) AS total
FROM deals d
JOIN users u ON u.id = d.owner_id
WHERE d.is_won = 1
GROUP BY u.id
ORDER BY total DESC

Common Table Expressions (WITH ...)

Sie können Daten in einer WITH-Klausel aufbereiten, bevor Ihr eigentliches SELECT läuft. Das ist das Muster „Daten abfragen, bevor Sie Ihre eigene Abfrage erstellen“, nützlich, wenn das Ergebnis von einer Zwischenberechnung abhängt:

WITH won_deals AS (
  SELECT owner_id, amount FROM deals WHERE is_won = 1
)
SELECT owner_id, SUM(amount) AS total
FROM won_deals
GROUP BY owner_id
ORDER BY total DESC

Dieselben Einschränkungen (nur lesend, kein SELECT *, keine gesperrten Tabellen, siehe unten) gelten sowohl für die CTE-Unterabfrage als auch für die Hauptanweisung.

Was die Abfrage darf und was nicht

Damit Berichte schnell und sicher bleiben, setzt Flexie diese Regeln zur Laufzeit durch.

Nur lesend

Nur SELECT und WITH werden akzeptiert. Alles, was Daten ändern oder löschen würde, wird beim Speichern abgelehnt: INSERT, UPDATE, DELETE, DROP, TRUNCATE, CREATE. Einen solchen Bericht können Sie nicht einmal speichern.

SELECT * ist verboten

Sie müssen die gewünschten Spalten auflisten. Die Abfrage wird abgelehnt, wenn sie SELECT * oder SELECT <table>.* verwendet. Gründe: Geschwindigkeit, und um die Spaltenliste für Filter und Sortierung vorhersehbar zu halten.

Harte Zeilengrenze von 1.000

Jeder Bericht ist auf 1.000 Zeilen begrenzt. Würde Ihre Abfrage von Natur aus mehr zurückgeben, werden nur die ersten 1.000 behalten. Wenn Sie ein LIMIT höher als 1.000 angeben, deckelt Flexie es stillschweigend. Brauchen Sie eine größere Gesamtsumme, aggregieren Sie innerhalb der Abfrage (SUM, COUNT, GROUP BY), statt im Template zu summieren.

Manche Tabellen sind tabu

Eine kurze Liste sensibler Tabellen kann nicht abgefragt werden: Einstellungen, Metadaten von Anhängen, Protokolle zu Lead-Punkteänderungen, IP-Querverweise, Mailbox- oder SMTP-Zugangsdaten, Add-on-Integrationseinstellungen. Wenn Sie darauf verweisen, erhalten Sie beim Speichern eine Fehlermeldung.

Platzhaltervariablen, die Flexie für Sie einsetzt

Fünf Tokens werden vor der Ausführung der Abfrage automatisch ersetzt, sodass Sie nutzerbezogene Berichte schreiben können, ohne IDs fest zu verdrahten:

Platzhalter Wird ersetzt durch
{user_id} Die ID des angemeldeten Nutzers
{group_id} Die Gruppen-ID des angemeldeten Nutzers (-1, falls in keiner)
{role_id} Die Rollen-ID des angemeldeten Nutzers (-1, falls keine vorhanden)
{timezone} Die Zeitzone des angemeldeten Nutzers (oder die Systemvorgabe, falls nicht gesetzt)
{filters} Das SQL-WHERE-Fragment, das aus den Nutzereingabe-Filtern erzeugt wird (siehe unten). Üblicherweise platzieren Sie es dort, wo die Filterbedingungen landen sollen.

{{user_id}} (mit doppelten Klammern) wird ebenfalls als Synonym akzeptiert.

Beispiele

-- Only deals the signed-in user owns
SELECT id, name, amount, stage_id
FROM deals
WHERE owner_id = {user_id}
ORDER BY date_added DESC
-- What this user's group is currently working on
SELECT id, name, owner_id, stage_id
FROM deals
WHERE owner_id IN (SELECT id FROM users WHERE group_id = {group_id})
ORDER BY date_modified DESC
-- Apply user-supplied filters where they belong in your query
SELECT id, name, amount, stage_id, date_added
FROM deals
WHERE is_published = 1
  {filters}
ORDER BY amount DESC

Wählt der Nutzer in den Filtern des Berichts „Status = Gewonnen“, wird {filters} durch AND stage_id IN (...) ersetzt, oder durch das, was der gewählte Filter sonst auflöst.

Nutzereingabe-Filter

Ein Bericht kann zur Anzeigezeit Filter anbieten: Drop-downs, Datumsauswahlen, Textfelder über dem Grid, die der Betrachter ausfüllen kann, um das Ergebnis einzugrenzen. Sie konfigurieren sie in der Filter-JSON-Einstellung des Berichts (der Filter-Editor unter /reports/filters/{id}).

Ein kurzer Vorgeschmack:

[
  {
    "alias": "date_added",
    "label": "Date Added",
    "type": "datetime"
  },
  {
    "alias": "is_won",
    "label": "Outcome",
    "type": "select",
    "properties": {
      "options": {
        "1": "Won",
        "0": "Lost or open"
      }
    }
  }
]

Das sind zwei Filter: ein Datumsbereich und ein Ja/Nein-Drop-down. Die Optionen eines select sind eine Schlüssel-zu-Label-Zuordnung: Der Schlüssel ist das, was in die Abfrage fließt, das Label ist das, was der Betrachter sieht.

Die sechs Filtertypen sind text, select, number, date, datetime und time. Der Betrachter erhält ein Operator-Drop-down für text, number und select; Datumstypen verwenden Von/Bis-Bereichsauswahlen.

Wo Filterwerte in Ihrer Abfrage landen

Enthält Ihre Abfrage {filters}, expandiert dieses Token zu den vom Nutzer gewählten Bedingungen als SQL-Fragment (oder zu 1=1, falls keine Filter aktiv sind):

SELECT id, name, amount, stage_id, date_added
FROM deals
WHERE is_published = 1
  AND {filters}
ORDER BY date_added DESC

Enthält Ihre Abfrage kein {filters}, werden die Werte trotzdem angewendet. Flexie umschließt Ihre Abfrage und schiebt sie für Sie in das äußere WHERE. Der Haken: Sie steuern nicht, wo sie landen. Verwenden Sie {filters}, wenn die Platzierung wichtig ist.

Filter können selbst per Flexie Scripting gesteuert werden

Das Filter-JSON wird durch Flexie Scripting gerendert, bevor es geparst wird. Die Optionen eines select können aus einer Live-Abfrage stammen (bauen Sie die Optionsliste mit einer {% for %}-Schleife über query("SELECT ...") auf), Labels können datumsbewusst sein und Filter können bedingt angezeigt werden.

Filter sind tiefgründig genug, um eine eigene Seite zu verdienen. Siehe Berichtsfilter (im Detail) für die vollständige Behandlung: jeder Typ und seine Operatoren, die drei Substitutionsmodi ({filters}-Platzhalter, automatisch und manual), die Variable __sql_filters und der Einsatz von Flexie Scripting im Filter-JSON, um dynamische Optionslisten zu bauen.

Spaltenverhalten zur Anzeigezeit

Der Nutzer kann mit dem Grid interagieren:

  • Klicken Sie auf einen beliebigen Spaltenkopf, um nach dieser Spalte zu sortieren. Erneutes Klicken kehrt die Reihenfolge um.
  • Ändern Sie die Seitengröße (Anzahl der Zeilen pro Seite).
  • Filter anwenden oder löschen über dem Grid.

Diese Entscheidungen werden pro Nutzer, pro Bericht gespeichert. Kommt der Nutzer zurück, sind sein letzter Filtersatz, seine Sortierung und seine Seitengröße noch vorhanden. Deshalb können zwei Personen denselben Bericht öffnen und leicht Unterschiedliches sehen; sie sehen nicht andere Daten, sondern dieselben Daten mit ihren eigenen Voreinstellungen.

Die Standardsortierung ergibt sich aus den Einstellungen Standard-Sortierspalte und Standard-Sortierrichtung des Berichts.

Validierung und Fehler

  • Beim Speichern prüft Flexie, dass Ihre Abfrage nur lesend ist, kein SELECT * verwendet und keine verbotenen Tabellen referenziert. Schlägt das fehl, wird der Bericht nicht gespeichert und Sie sehen den Grund.
  • Zur Anzeigezeit, falls die Abfrage einen Syntaxfehler enthält, sehen Sie den Datenbankfehler auf der Ansichtsseite (und nur Personen, die den Bericht ansehen dürfen, sehen ihn). Korrigieren Sie die Abfrage und speichern Sie.

Performance-Tipps

  • Aggregieren Sie in der Abfrage. Holen Sie nicht 10.000 Zeilen, um sie im Template zu summieren; verwenden Sie SUM, COUNT, GROUP BY im SELECT.
  • Filtern Sie früh. Setzen Sie eingrenzende WHERE-Klauseln zuerst auf die größten Tabellen.
  • Index-freundliche Spalten im WHERE. Gleichheit auf indizierten Spalten (id, owner_id, is_won, stage_id) ist schnell; LIKE '%…%' auf einer Freitextspalte ist langsam.
  • Vermeiden Sie breite Joins, wenn eine Unterabfrage oder CTE genügen würde.
  • Die 1.000-Zeilen-Grenze ist Ihr Freund. Eine Abfrage, die Millionen von Zeilen zurückgeben könnte, wird durch LIMIT 1000 nicht plötzlich sicher; die Datenbank scannt möglicherweise trotzdem alles, um die ersten 1.000 zu finden. Erst filtern, dann begrenzen.

Nächste Schritte