Laden & Aufbereiten
Kleine Testdaten laden
Im Ladescript synthetische Daten für die weiteren Beispiele anlegen.
Orders:
LOAD * INLINE [
OrderID, Customer, Year, Sales
1, A, 2026, 10
2, A, 2025, 20
3, B, 2026, 30
];
Nur Testdaten; Reload verändert das App-Datenmodell.
Laden & Aufbereiten
Resident aggregieren
Setzt die Tabelle Orders aus dem ersten Beispiel voraus.
CustomerTotals:
LOAD Customer, Sum(Sales) AS CustomerSales
RESIDENT Orders
GROUP BY Customer;
Nicht aggregierte geladene Felder müssen zur GROUP-BY-Granularität passen.
Abfragen & Kennzahlen
Aktuelle Auswahl auswerten
Diagrammausdruck auf dem geladenen Feld Sales.
Sum(Sales)
Ohne Auswahl ergeben die Beispieldaten 60; Auswahl und Dimensionen beeinflussen das Ergebnis.
Abfragen & Kennzahlen
Jahr im Set festlegen
Im Diagramm Year auf 2026 setzen, andere Auswahlfelder beibehalten.
Sum({$<Year={2026}>} Sales)
Ohne weitere Auswahl ergeben die Beispieldaten 40. Set Analysis ist keine Sicherheitsgrenze.
Abfragen & Kennzahlen
Eindeutige Werte zählen
Diagrammausdruck für eindeutige Kundenwerte.
Count(DISTINCT Customer)
Ohne Auswahl ergeben die Beispieldaten 2; das ist keine automatische fachliche Kundendeduplizierung.
Abfragen & Kennzahlen
Dimensionsgrenze aufheben
Diagrammanteil innerhalb der aktuellen Auswahl bilden.
Sum(Sales) / Sum(TOTAL Sales)
TOTAL ignoriert hier Diagrammdimensionen, nicht die aktuelle Auswahl; Nenner 0/NULL berücksichtigen.
Laden & Aufbereiten
Preceding Load verwenden
Interpretation und Darstellung eines Datums trennen.
Orders:
LOAD OrderID, Date(Date#(OrderDateText, 'YYYY-MM-DD')) AS OrderDate;
LOAD * INLINE [
OrderID, OrderDateText
1, 2026-10-01
];
Date# interpretiert Text; Date formatiert einen numerischen Datumswert.
Laden & Aufbereiten
Werte mit Mapping ergänzen
Einzelnen Zielwert ohne vervielfachenden Join zuordnen.
RegionMap:
MAPPING LOAD * INLINE [
Code, Region
W, West
E, East
];
OrdersWithRegion:
NoConcatenate
LOAD *, ApplyMap('RegionMap', RegionCode, 'UNKNOWN') AS RegionName
RESIDENT Orders;
Orders muss RegionCode enthalten. UNKNOWN anschließend als Datenqualitätsfall zählen.
Laden & Aufbereiten
Automatische Verkettung verhindern
Eine gleich strukturierte Tabelle bewusst getrennt erzeugen.
OrdersCopy:
NoConcatenate
LOAD * RESIDENT Orders;
Gleiche Feldnamen können weiterhin Assoziationen oder synthetische Schlüssel erzeugen.
Laden & Aufbereiten
Existierende Schlüssel filtern
Auf eine zuvor geladene Feldwertmenge einschränken.
OrdersSelected:
NoConcatenate
LOAD * RESIDENT Orders
WHERE Exists(AllowedCustomer, Customer);
AllowedCustomer vorher laden. Exists ist ein Ladefilter und kein Ersatz für Zugriffssicherheit.
Abfragen & Kennzahlen
Zahlenbereich in Set Analysis
Werte zwischen 10 einschließlich und 100 ausschließlich auswählen.
Sum({$<Sales={">=10<100"}>} Sales)
Dieser Modifier ersetzt die Auswahl auf Sales im aktuellen Set; keine Zeilenrechte.
Abfragen & Kennzahlen
Ein Feld im Set zurücksetzen
Jahresauswahl für diese Kennzahl aufheben und andere Auswahlen behalten.
Sum({$<Year=>} Sales)
Kann fachlich andere Vergleichsmengen erzeugen; Kennzahl eindeutig beschriften.
Datenqualität
Mehrdeutige Auswahl erkennen
Genau einen möglichen Wert anzeigen.
Only(Customer)
Bei keinem oder mehreren möglichen Werten ergibt sich NULL. Kein allgemeiner Ersatz für Min oder Max.
Modellierung
Persistenten Verbundschlüssel bilden
Schlüssel aus mehreren Feldern unabhängig von Lade-Reihenfolge bilden.
LOAD
Hash128(CustomerID, RegionCode) AS CustomerRegionKey,
CustomerID, RegionCode
RESIDENT Customers;
Hash ist keine zugesicherte Anonymisierung. AutoNumberHash128 liefert ladeabhängige Ganzzahlen und ist für getrennte Läufe anders zu bewerten.
Sicherheit & Rechte
Section Access kontrolliert testen
Vor Veröffentlichung Schutz mit synthetischen Testnutzern belegen.
Erlaubte Identität → Sollzeilen sichtbar
Nicht berechtigte Identität → kein Zugriff
Mehrfachgruppen → effektive Reduktion prüfen
Entzug → neue Sitzung und Nachtest
Export/Kopien → getrennte Bewertung
Bereichsrechte und App-Datenreduktion sind getrennte Ebenen. Keine ungeprüfte Security-Tabelle in Produktion laden. Mit separaten Testkonten erlaubte und verbotene Regionen sowie App-Export und Rohdatenzugriff prüfen. Reduktionsfelder und Werte in Section Access müssen großgeschrieben sein; Identitätsfeld und Claims gegen den eigenen Identity Provider abgleichen.
Metadaten & Katalog
QVD-Zeilenzahl im Skript lesen
Eine zugreifbare QVD-Datei vor dem vollständigen Laden einschätzen.
LET vRows = QvdNoOfRecords('lib://DataFiles/orders.qvd');
TRACE QVD rows: $(vRows);
Bibliotheksverbindung und Dateirechte bestätigen. Eine Zeilenzahl ist kein Qualitätsnachweis.
Metadaten & Katalog
QVD-Feldzahl lesen
Metadateninventar einer vorhandenen QVD ergänzen.
LET vFields = QvdNoOfFields('lib://DataFiles/orders.qvd');
Kein Ersatz für Feldnamen, Typen und fachliche Bedeutung.
Laden & Aufbereiten
Wert aus geladener Tabelle lesen
Letzte geladene Zeile einer benannten Tabelle untersuchen.
LET vLastOrder = Peek('OrderID', -1, 'Orders');
Ladereihenfolge ist nicht automatisch fachliche Zeitreihenfolge; leere Tabelle gesondert behandeln.
Datenqualität
Leere Kundenkennung zählen
Fehlende Kennungen als Kennzahl sichtbar machen.
Sum(If(IsNull(Customer) or Len(Trim(Customer)) = 0, 1, 0))
Leere Texte, NULL und spezielle Leerzeichen getrennt mit synthetischen Fällen prüfen.
Datenqualität
Doppelte Mapping-Schlüssel finden
Vor MAPPING LOAD Mehrdeutigkeit in der Quelle erkennen.
MappingKeyCounts:
LOAD RegionCode, Count(RegionCode) AS KeyCount
RESIDENT RegionSource
GROUP BY RegionCode;
RegionSource vorher laden. KeyCount > 1 zeigt Mehrfachbelegung; NULL-Schlüssel separat prüfen.
Laden & Aufbereiten
Datum lesen statt nur formatieren
Ladeskript: Datumstext zuerst interpretieren und anschließend darstellen.
Orders:
LOAD OrderID,
Date(Date#(OrderDateText, 'DD.MM.YYYY'), 'YYYY-MM-DD') AS OrderDate
RESIDENT RawOrders;
RawOrders wird vorausgesetzt. Date# interpretiert, Date formatiert. Fehlgeschlagene Interpretation mit Testwerten prüfen; Rohtext nicht vorzeitig löschen.
Laden & Aufbereiten
Zeitstempel auf Tageskorn bringen
Ladeskript: Uhrzeit numerisch entfernen, bevor nach Tagen verknüpft wird.
Orders:
LOAD OrderID,
Date(Floor(Timestamp#(OrderTimestampText,
'YYYY-MM-DD hh:mm:ss')), 'YYYY-MM-DD') AS OrderDate
RESIDENT RawOrders;
RawOrders und das angegebene Eingabeformat werden vorausgesetzt. Floor verändert den numerischen Wert; Date allein versteckt die Uhrzeit nur. Zeitzone vor der Tagesbildung klären.
Datenqualität
Dezimal- und Tausenderzeichen festlegen
Ladeskript: einen deutschen Zahlenwert unabhängig von Standardeinstellungen lesen.
NumberCheck:
LOAD
Num#('1.234,56', '#.##0,00', ',', '.') AS Amount
AUTOGENERATE 1;
Erwarteter numerischer Wert: 1234,56. Anzeigeformatierung ist ein eigener Schritt. Gemischte Quellformate nicht blind mit derselben Regel einlesen.
Datenqualität
Leere Kennungen in NULL überführen
Ladeskript: NULL und leere Texte einheitlich behandeln.
Customers:
NOCONCATENATE
LOAD CustomerID,
If(IsNull(CustomerCode) OR Len(Trim(CustomerCode)) = 0,
Null(), Trim(CustomerCode)) AS CustomerCode
RESIDENT RawCustomers;
RawCustomers wird vorausgesetzt. NULL-Werte verbinden sich nicht wie normale Schlüsselwerte. Rohwert und fehlende Zuordnungen separat prüfen.
Modellierung
Faktentabellen ausdrücklich verketten
Ladeskript: aktuelle und historische Fakten mit gleicher Spaltenbedeutung anhängen.
Facts:
NOCONCATENATE
LOAD OrderID, OrderDate, Amount
RESIDENT CurrentOrders;
CONCATENATE (Facts)
LOAD OrderID, OrderDate, Amount
RESIDENT ArchivedOrders;
DROP TABLES CurrentOrders, ArchivedOrders;
Beide Quelltabellen müssen existieren. CONCATENATE entfernt keine Dubletten. Zeitüberschneidungen und gemeinsame Schlüssel prüfen, bevor die Hilfstabellen entfernt werden.
Modellierung
Dimension mit KEEP begrenzen
Ladeskript: nur Kunden behalten, die auch in Facts vorkommen.
Customers:
LEFT KEEP (Facts)
LOAD CustomerID, CustomerName
RESIDENT RawCustomers;
DROP TABLE RawCustomers;
Facts muss bereits geladen sein. KEEP behält zwei Tabellen und verknüpft sie nicht zu einer einzigen. Alle gemeinsamen Feldnamen beeinflussen den Abgleich.
Modellierung
Ungewollte Feldverbindungen vermeiden
Ladeskript: Feldnamen qualifizieren und nur den beabsichtigten Schlüssel freigeben.
QUALIFY *;
UNQUALIFY CustomerID;
Customers:
LOAD CustomerID, CustomerName, Status
RESIDENT RawCustomers;
UNQUALIFY *;
DROP TABLE RawCustomers;
Danach heißen Felder etwa Customers.Status. QUALIFY gilt für folgende LOADs; den Zustand gezielt zurücksetzen. Mit Teil-Reloads nicht verwenden; Modellverbindungen prüfen.
Modellierung
Monatsspalten mit Crosstable entpivotieren
Ladeskript: aus einer Excel-artigen Monatsmatrix eine lange Faktentabelle bauen.
MonthlySales:
CROSSTABLE (MonthText, Sales, 1)
LOAD * INLINE [
Product, Jan, Feb
A, 100, 120
B, 80, 95
];
1 bezeichnet die unveränderte erste Spalte Product. MonthText ist zunächst Text; für mehrere Jahre einen eindeutigen Jahr-Monat-Schlüssel ergänzen.
Laden & Aufbereiten
Kleinen Kalender lückenlos erzeugen
Ladeskript: jeden Tag im Oktober 2026 mit IterNo erzeugen.
Calendar:
LOAD Date(MakeDate(2026,10,1) + IterNo() - 1, 'YYYY-MM-DD')
AS OrderDate
AUTOGENERATE 1
WHILE MakeDate(2026,10,1) + IterNo() - 1 <= MakeDate(2026,10,31);
Erwartet: 31 Tage. WHILE braucht eine endliche Grenze. OrderDate muss zum numerischen Tageskorn der Fakten passen.
Betrieb & Fehlersuche
Freigegebene Felder als QVD speichern
Ladeskript: nur festgelegte Spalten einer geladenen Tabelle exportieren.
STORE OrderID, OrderDate, Amount
FROM Orders
INTO [lib://DataFiles/orders_curated.qvd] (qvd);
Schreibt eine Datei und kann eine vorhandene Datei ersetzen. Verbindung, Zielbereich, Schreibrecht und Aufbewahrung prüfen. QVD-Zugriff ist getrennt vom App-Zugriff zu regeln.
Sicherheit & Rechte
PII vor der App gezielt weglassen
Ladeskript: eine kuratierte Tabelle ohne Namen oder E-Mail-Adressen laden.
CustomerApp:
NOCONCATENATE
LOAD CustomerKey, Region, Segment
RESIDENT RawCustomers;
DROP TABLE RawCustomers;
CustomerKey, Region und Segment können weiterhin identifizierend sein. Dies ist Datenminimierung, keine Anonymisierung. Rohquellen, QVDs, Berechtigungen und Section Access separat absichern.
Betrieb & Fehlersuche
Zeilenzahl nach dem Laden protokollieren
Ladeskript: geladene Zeilen ohne Datensatzinhalte ins Ladeprotokoll schreiben.
LET vOrderRows = NoOfRows('Orders');
TRACE Orders rows: $(vOrderRows);
Orders muss vollständig geladen sein. Zeilenzahl ist kein Beweis für Vollständigkeit oder Datenqualität. Keine PII, Tokens oder Passwörter mit TRACE ausgeben.
Laden & Aufbereiten
SET und LET unterscheiden
Ladeskript: Textzuweisung und ausgewerteten Ausdruck vergleichen.
SET vExpression = 1 + 2;
LET vResult = 1 + 2;
TRACE Expression: $(vExpression);
TRACE Result: $(vResult);
vExpression enthält den Text 1 + 2; vResult den Wert 3. Dollar-Sign-Expansion setzt Text ein; keine unkontrollierten Benutzereingaben in Skript oder Ausdrücke übernehmen.
Abfragen & Kennzahlen
Jahresauswahl schneiden statt ersetzen
Diagramm: bestehende Jahresauswahl mit 2026 überschneiden.
Sum({$<Year *= {2026}>} Sales)
Bei Auswahl nur 2025 gibt es keine passenden Zeilen. *= bildet die Schnittmenge; = würde die Feldauswahl ersetzen. Set Analysis ist keine Zugriffskontrolle.
Abfragen & Kennzahlen
Kennzahl ohne aktuelle Auswahl
Diagramm: mit Set Identifier 1 die aktuelle Auswahl ignorieren.
Sum({1} Sales)
Ignoriert Auswahlen, aber keine Section-Access-Datenreduktion. Nicht als Berechtigungsprüfung oder als Garantie verwenden, dass alle Quellsystemdaten geladen wurden.
Abfragen & Kennzahlen
Durchschnitt aus Kundensummen bilden
Diagramm: zuerst je Kunde summieren und anschließend diese Summen mitteln.
Avg(Aggr(Sum(Sales), CustomerID))
Unterscheidet sich vom Durchschnitt der Faktzeilen. Auswahl, Diagrammdimensionen, NULL-Kunden und Kunden ohne Fakten beeinflussen die Grundgesamtheit.
Abfragen & Kennzahlen
Bezeichnung des jüngsten Datensatzes
Diagramm: einen Status über den höchsten numerischen Zeitstempel auswählen.
FirstSortedValue(Status, -UpdatedAt)
UpdatedAt muss numerisch interpretiert sein. Mehrere Werte mit gleichem Sortiergewicht können NULL liefern. Keine zufällige Eindeutigkeit durch Weglassen der Prüfung erzeugen.
Abfragen & Kennzahlen
Kumulierte Summe im Diagramm
Diagramm: die aktuelle und alle vorherigen sichtbaren Zeilen summieren.
RangeSum(Above(Sum(Sales), 0, RowNo()))
Für eine einfache Tabelle mit aufsteigend sortiertem OrderDate. Dimensions- und Segmentsortierung bestimmen das Ergebnis; fehlende Tage werden nicht automatisch ergänzt. Keine Sortierung nach der Kennzahl erzwingen.
Abfragen & Kennzahlen
Ausgewählte Regionen zählen
Diagramm: die Anzahl ausdrücklich ausgewählter Werte anzeigen.
GetSelectedCount(Region)
Zählt ausgewählte Werte und nicht alle möglichen Werte. Ausgewählte ausgeschlossene Werte sind standardmäßig nicht enthalten. Daraus keine Berechtigung oder Datenfreigabe ableiten.
Laden & Aufbereiten
Differenz im sortierten Ladeskript
Ladeskript: den Vorgänger je Kunde nur in einer definierten Reihenfolge vergleichen.
OrderChanges:
NOCONCATENATE
LOAD OrderID, CustomerID, OrderDate, Amount,
If(CustomerID = Previous(CustomerID),
Amount - Previous(Amount), Null()) AS AmountDelta
RESIDENT Orders
ORDER BY CustomerID, OrderDate, OrderID;
Orders muss vorhanden sein. Erste Zeile je Kunde liefert NULL. Ein nachträglicher WHERE-Filter kann die Bedeutung von Previous verändern; auf diesem Beispiel keinen Filter ergänzen, ohne die Semantik zu prüfen.