Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Der Daten-API-Generator (DAB) unterstützt die GraphQL-Aggregation und -Gruppierung für SQL-Familiendatenbanken und Azure Synapse Analytics (dedizierter SQL-Pool). Mithilfe von Aggregationen können Sie numerische Felder und Gruppenergebnisse zusammenfassen, ohne benutzerdefinierten API-Code zu schreiben. Aggregation und groupBy sind für Azure Cosmos DB für NoSQL, PostgreSQL oder MySQL nicht verfügbar.
Voraussetzungen
- Unterstützte Datenbank:
- SQL Server 2016 oder höher
- Azure SQL-Datenbank
- Verwaltete Azure SQL-Instanz
- Microsoft Fabric SQL
- Azure Synapse Analytics (nur dedizierter SQL-Pool)
- CLI des Daten-API-Erstellers. Installieren der CLI
- Eine DAB-Konfigurationsdatei mit Ihrer Entität, die über GraphQL verfügbar gemacht wird.
- Ein GraphQL-Client (z. B. Banana Cake Pop oder GraphQL Playground), um Abfragen auszuführen.
Unterstützte Datenbanken
| Datenbank | Aggregationsunterstützung |
|---|---|
| SQL Server / Azure SQL / Microsoft Fabric SQL | ✅ Ja |
| Azure Synapse (dedizierter SQL-Pool) | ✅ Ja |
| Azure Synapse (Serverless SQL-Pool) | ❌ Nein |
| PostgreSQL | ❌ Nein |
| MySQL | ❌ Nein |
| Azure Cosmos DB für NoSQL-Datenbanklösungen | ❌ Nein |
Aggregatfunktionen
DAB unterstützt die folgenden Aggregatfunktionen:
| Funktion | Gilt für: | Description |
|---|---|---|
sum |
Nur numerische Felder | Summe aller Werte |
average |
Nur numerische Felder | Mittelwert aller Werte |
min |
Nur numerische Felder | Minimalwert |
max |
Nur numerische Felder | Maximalwert |
count |
Beliebiges Feld | Anzahl von Nicht-Null-Werten |
Constraints
-
sum,average,minundmaxfunktionieren nur für numerische Datentypen (int, dezimal, float usw.). -
countfunktioniert für jeden Datentyp, einschließlich Zeichenfolgen und Datumsangaben. - Wenn eine Tabelle keine numerischen Spalten enthält, generiert DAB keine Aggregationsknoten für diese Entität. Sie können weiterhin für nicht numerische Felder verwenden
count.
Optionale Modifizierer
| Modifikator | Zweck | Example |
|---|---|---|
distinct: true |
Nur eindeutige Werte zählen | Zählen unterschiedliche Kunden |
having: { ... } |
Filtern von Gruppen nach aggregation | Gruppen mit Summe > 1000 anzeigen |
Die DAB-Laufzeitumgebung ausführen
Starten Sie DAB mit Ihrer Konfigurationsdatei, damit der GraphQL-Endpunkt verfügbar ist.
dab start
Aggregierte Ergebnisse abfragen
In diesem Abschnitt wird ein vollständiges Beispiel für das Tabellenschema, die GraphQL-Abfrage, die generierte SQL- und JSON-Antwort erläutert.
Tabellenschema
CREATE TABLE books (
id INT PRIMARY KEY,
title NVARCHAR(200),
year INT,
pages INT
);
GraphQL-Abfrage
Verwenden Sie GraphQL, um Zeilen zu gruppieren und Aggregatwerte für numerische Felder zurückzugeben.
{
books(
groupBy: { fields: ["year"] }
) {
items {
year
}
aggregates {
pages {
sum
average
min
max
}
}
}
}
-
groupBy.fieldsgruppiert Zeilen nach den angegebenen Spalten. -
aggregatesmacht Aggregatfunktionen für numerische Felder verfügbar (z. Bpages. ). - Das GraphQL-Schema macht nur Aggregate für Felder verfügbar, die sie unterstützen; Verwenden Sie die Schemaintrospection in Ihrem Client, um verfügbare Aggregatfelder und -funktionen zu bestätigen.
Generiertes SQL
DAB übersetzt die GraphQL-Abfrage in T-SQL:
SELECT
[year],
SUM([pages]) AS [sum],
AVG([pages]) AS [average],
MIN([pages]) AS [min],
MAX([pages]) AS [max]
FROM [dbo].[books]
GROUP BY [year]
FOR JSON PATH, INCLUDE_NULL_VALUES
JSON-Antwort
{
"data": {
"books": {
"items": [
{ "year": 2023 },
{ "year": 2024 }
],
"aggregates": {
"pages": [
{ "sum": 3200, "average": 320, "min": 120, "max": 450 },
{ "sum": 4500, "average": 300, "min": 140, "max": 510 }
]
}
}
}
}
Die items und aggregates Arrays werden nach Index ausgerichtet – das erste Element in aggregates.pages entspricht der ersten Gruppe in items.
Aggregat ohne Gruppierung
Berechnen von Aggregaten über alle Zeilen hinweg, wenn groupBy weggelassen wird.
GraphQL-Abfrage
{
books {
aggregates {
pages {
sum
average
min
max
count
}
id {
count
}
}
}
}
Generiertes SQL
SELECT
SUM([pages]) AS [sum],
AVG([pages]) AS [average],
MIN([pages]) AS [min],
MAX([pages]) AS [max],
COUNT([pages]) AS [count],
COUNT([id]) AS [count]
FROM [dbo].[books]
FOR JSON PATH, INCLUDE_NULL_VALUES
JSON-Antwort
{
"data": {
"books": {
"aggregates": {
"pages": {
"sum": 15420,
"average": 308,
"min": 120,
"max": 850,
"count": 50
},
"id": {
"count": 50
}
}
}
}
}
Ohne groupBy, gibt die Antwort ein einzelnes Objekt (kein Array) zurück, da alle Zeilen in ein Ergebnis reduziert werden.
Gruppieren nach einem oder mehreren Feldern
Gruppieren Sie Zeilen nach einer oder mehreren Spalten, und geben Sie Aggregate pro Gruppe zurück.
Tabellenschema
CREATE TABLE sales (
id INT PRIMARY KEY,
year INT,
category NVARCHAR(50),
revenue DECIMAL(10,2),
quantity INT
);
GraphQL-Abfrage
{
sales(
groupBy: { fields: ["year", "category"] }
) {
items {
year
category
}
aggregates {
revenue {
sum
average
}
quantity {
sum
}
}
}
}
Generiertes SQL
SELECT
[year],
[category],
SUM([revenue]) AS [sum],
AVG([revenue]) AS [average],
SUM([quantity]) AS [sum]
FROM [dbo].[sales]
GROUP BY [year], [category]
FOR JSON PATH, INCLUDE_NULL_VALUES
JSON-Antwort
{
"data": {
"sales": {
"items": [
{ "year": 2023, "category": "Books" },
{ "year": 2023, "category": "Electronics" },
{ "year": 2024, "category": "Books" }
],
"aggregates": {
"revenue": [
{ "sum": 45000.00, "average": 150.00 },
{ "sum": 120000.00, "average": 600.00 },
{ "sum": 52000.00, "average": 173.33 }
],
"quantity": [
{ "sum": 300 },
{ "sum": 200 },
{ "sum": 300 }
]
}
}
}
}
Die Antwort gibt Arrays für items und Aggregate in derselben Reihenfolge zurück, sodass Sie Gruppen mit ihren aggregierten Werten ausrichten können.
Das Filtern von aggregierten Ergebnissen müssen
Verwenden Sie having, um Gruppen nach der Aggregation zu filtern. Dies entspricht der SQL-Klausel HAVING .
Tabellenschema
CREATE TABLE products (
id INT PRIMARY KEY,
category NVARCHAR(50),
price DECIMAL(10,2)
);
GraphQL-Abfrage
{
products(
groupBy: { fields: ["category"] }
) {
items { category }
aggregates {
price {
sum(having: { gt: 10000 })
average
}
}
}
}
Generiertes SQL
SELECT
[category],
SUM([price]) AS [sum],
AVG([price]) AS [average]
FROM [dbo].[products]
GROUP BY [category]
HAVING SUM([price]) > 10000
FOR JSON PATH, INCLUDE_NULL_VALUES
JSON-Antwort
Es werden nur Kategorien zurückgegeben, in denen die Summe 10000 überschreitet:
{
"data": {
"products": {
"items": [
{ "category": "Electronics" },
{ "category": "Furniture" }
],
"aggregates": {
"price": [
{ "sum": 15000.00, "average": 300.00 },
{ "sum": 12000.00, "average": 400.00 }
]
}
}
}
}
HAVING-Operatoren
| Bediener | SQL-Entsprechung | Example |
|---|---|---|
eq |
= |
having: { eq: 100 } |
neq |
<> |
having: { neq: 0 } |
gt |
> |
having: { gt: 1000 } |
gte |
>= |
having: { gte: 500 } |
lt |
< |
having: { lt: 100 } |
lte |
<= |
having: { lte: 50 } |
Hinweis
Jeder having Filter wird unabhängig von seiner Aggregatfunktion angewendet. Sie können keine aggregatübergreifenden Bedingungen wie "Summe > 1000 ODER Anzahl < 10" in einer einzelnen GraphQL-Abfrage erstellen.
DISTINCT in Aggregationen
Zähle eindeutige Werte mit distinct: true.
Tabellenschema
CREATE TABLE orders (
id INT PRIMARY KEY,
customer_id INT,
product_id INT
);
GraphQL-Abfrage
{
orders(
groupBy: { fields: ["customer_id"] }
) {
items { customer_id }
aggregates {
product_id {
count(distinct: true)
count
}
}
}
}
Generiertes SQL
SELECT
[customer_id],
COUNT(DISTINCT [product_id]) AS [count],
COUNT([product_id]) AS [count]
FROM [dbo].[orders]
GROUP BY [customer_id]
FOR JSON PATH, INCLUDE_NULL_VALUES
JSON-Antwort
{
"data": {
"orders": {
"items": [
{ "customer_id": 101 },
{ "customer_id": 102 }
],
"aggregates": {
"product_id": [
{ "count": 5 },
{ "count": 3 }
]
}
}
}
}
Der erste count (mit distinct: true) gibt eindeutige Produkte pro Kunde zurück. Die zweite count gibt Gesamtbestellungen zurück.
Hinweis
Beim Anfordern mehrerer Aggregate für dasselbe Feld gibt DAB sie in der angeforderten Reihenfolge zurück. Verwenden Sie Aliase (z. B uniqueProducts: count(distinct: true). ), um Antworten selbst dokumentieren zu können.
Kombinieren von Filtern mit Aggregation
Wenden Sie filter auf Zeilen vor der Gruppierung an und having auf Gruppen nach der Aggregation. Das Verständnis der Reihenfolge von Vorgängen ist wichtig:
-
Filter (SQL
WHERE) entfernt Zeilen vor der Gruppierung - Gruppieren durch Sammeln verbleibender Zeilen in Gruppen
- Aggregat berechnet summe/avg/min/max/count pro Gruppe
- Das Verwenden von 'Having'-Anweisung entfernt Gruppen, die nicht mit der Bedingung übereinstimmen
GraphQL-Abfrage
{
sales(
filter: { year: { gte: 2023 } }
groupBy: { fields: ["region"] }
) {
items { region }
aggregates {
revenue { sum average }
}
}
}
Generiertes SQL
SELECT
[region],
SUM([revenue]) AS [sum],
AVG([revenue]) AS [average]
FROM [dbo].[sales]
WHERE [year] >= 2023
GROUP BY [region]
FOR JSON PATH, INCLUDE_NULL_VALUES
Tipp
Verwenden Sie filter, um Zeilen vor der Aggregation auszuschließen. Verwenden Sie having, um Gruppen nach der Aggregation zu filtern.
Verwenden von Aliasen mit Aggregationen
Erstellen Sie aussagekräftige Feldnamen mithilfe von GraphQL-Aliasen.
{
products(
groupBy: { fields: ["category"] }
) {
items { category }
aggregates {
price {
totalRevenue: sum
avgPrice: average
cheapest: min
mostExpensive: max
productCount: count
}
}
}
}
Schema-Introspektion
Verwenden Sie "Introspection", um zu sehen, welche Aggregate für eine Entität verfügbar sind.
{
__type(name: "BooksAggregates") {
fields {
name
type { name }
}
}
}
Numerische Felder stellen sum, average, min, max und count bereit. Nicht-numerische Felder legen count frei.
Tipps und Einschränkungen
- Aggregation und
groupBygilt nur für SQL Server-, Azure SQL-, Microsoft Fabric SQL- und Azure Synapse Dedicated SQL-Pool. - Aggregate werden in numerischen Feldern ausgeführt;
countfunktioniert für jedes Feld. Tabellen ohne numerische Spalten zeigen nurcount. - Die Gruppierung gilt für Felder in derselben Entität (keine entitätsübergreifende GroupBy).
- Große Aggregationen können teuer sein; indizieren Sie Ihre groupBy-Spalten und filtern Sie Zeilen, bevor Sie nach Möglichkeit gruppieren.
- Erstellen Sie Indizes für häufig verwendete
groupBySpalten, um die Abfrageleistung zu verbessern.
Problembehandlung
Fehler: Das Feld unterstützt keine Aggregation.
Ursache: Verwenden von sum, average, min oder max für ein nicht numerisches Feld.
Lösung:
- Verwenden Sie die Schemaintrospection, um Feldtypen zu überprüfen.
- Wird für nicht numerische Felder verwendet
count. - Überprüfen Sie Feldzuordnungen, wenn Sie benutzerdefinierte Feldnamen verwenden.
Fehler: Aggregationsknoten nicht gefunden
Ursache: Die Entität hat keine numerischen Spalten.
Lösung:
- Stellen Sie sicher, dass das Tabellenschema mindestens eine numerische Spalte aufweist.
- Verwenden Sie
countAggregate bei Bedarf für nicht numerische Felder.
Langsame Aggregationsabfragen
Ursache: Große Tabellen ohne ordnungsgemäße Indizes.
Lösung:
- Erstellen Sie Indizes für
groupBySpalten. - Verwenden Sie
filter, um Zeilen vor der Aggregation einzuschränken. - Verwenden Sie
having, um die Anzahl der zurückgegebenen Gruppen zu verringern.