Megosztás:


Adatok összesítése a GraphQL-lel a Data API Builderben

A Data API Builder (DAB) támogatja a GraphQL-összesítést és csoportosítást az SQL családi adatbázisokhoz és az Azure Synapse Analyticshez (dedikált SQL-készlet). Az aggregációk lehetővé teszik a numerikus mezők és a csoporteredmények összegzését egyéni API-kód írása nélkül. Aggregáció, és groupBy nem érhetők el az Azure Cosmos DB for NoSQL, a PostgreSQL vagy a MySQL esetében.

Előfeltételek

  • Támogatott adatbázis:
    • SQL Server 2016 vagy újabb
    • Azure SQL Database
    • Azure SQL Managed Instance
    • Microsoft Fabric SQL
    • Azure Synapse Analytics (csak dedikált SQL-készlet)
  • Adat API-építő CLI. A parancssori felület telepítése
  • Egy DAB-konfigurációs fájl, amely az entitást GraphQL-en keresztül teszi elérhetővé.
  • Egy GraphQL-ügyfél (például Banana Cake Pop vagy GraphQL Playground) lekérdezések futtatásához.

Támogatott adatbázisok

Adatbázis Összesítés támogatása
SQL Server / Azure SQL / Microsoft Fabric SQL ✅ Igen
Azure Synapse (dedikált SQL-készlet) ✅ Igen
Azure Synapse (kiszolgáló nélküli SQL-készlet) ❌ Nem
PostgreSQL ❌ Nem
MySQL ❌ Nem
Azure Cosmos DB for NoSQL ❌ Nem

Összesítő függvények

A DAB a következő összesítő függvényeket támogatja:

Funkció A következőkre vonatkozik: Description
sum Csak numerikus mezők Az összes érték összesen
average Csak numerikus mezők Az összes érték középértéke
min Csak numerikus mezők Minimális érték
max Csak numerikus mezők Maximális érték
count Bármely mező Nem null értékek száma

Constraints

  • sum, average, minés max csak numerikus adattípusokon (int, decimális, lebegőpontos stb.) dolgozik.
  • count Bármilyen adattípuson működik, beleértve a sztringeket és a dátumokat is.
  • Ha egy tábla nem tartalmaz numerikus oszlopokat, a DAB nem hoz létre aggregációs csomópontokat az adott entitáshoz. A nem numerikus mezőkön továbbra is használható count .

Választható módosítók

Módosító Cél Example
distinct: true Csak az egyedi értékek számítása Eltérő ügyfelek száma
having: { ... } Csoportok szűrése az összesítés után Csoportok megjelenítése 1000 összeggel >

A DAB-futtatókörnyezet futtatása

Indítsa el a DAB-t a konfigurációs fájllal, hogy elérhető legyen a GraphQL-végpont.

dab start

Összesített eredmények lekérdezése

Ez a szakasz végigvezet egy teljes példán, amely bemutatja a táblázatsémát, a GraphQL-lekérdezést, a generált SQL-t és a JSON-választ.

Táblaséma

CREATE TABLE books (
    id INT PRIMARY KEY,
    title NVARCHAR(200),
    year INT,
    pages INT
);

GraphQL-lekérdezés

A GraphQL használatával csoportosíthatja a sorokat, és visszaadhatja a numerikus mezők összesített értékeit.

{
  books(
    groupBy: { fields: ["year"] }
  ) {
    items {
      year
    }
    aggregates {
      pages {
        sum
        average
        min
        max
      }
    }
  }
}
  • groupBy.fields csoportosítja a sorokat a megadott oszlopok szerint.
  • aggregates a numerikus mezők összesítő függvényeit teszi elérhetővé (például pages).
  • A GraphQL-séma csak az őket támogató mezők összesítéseit teszi elérhetővé; sémabetekintés használata az ügyfélben az elérhető összesítő mezők és függvények megerősítéséhez.

Generált SQL

A DAB a GraphQL-lekérdezést T-SQL-ként fordítja le:

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-válasz

{
  "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 }
        ]
      }
    }
  }
}

A items tömbök index aggregates szerint vannak igazítva – az első elem aggregates.pages az első csoportnak itemsfelel meg.

Összesítés csoportosítás nélkül

Számítsd ki az összes sor összesítését, amikor kihagyod a groupBy elemet.

GraphQL-lekérdezés

{
  books {
    aggregates {
      pages {
        sum
        average
        min
        max
        count
      }
      id {
        count
      }
    }
  }
}

Generált 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-válasz

{
  "data": {
    "books": {
      "aggregates": {
        "pages": {
          "sum": 15420,
          "average": 308,
          "min": 120,
          "max": 850,
          "count": 50
        },
        "id": {
          "count": 50
        }
      }
    }
  }
}

E nélkül groupBya válasz egyetlen objektumot (nem tömböt) ad vissza, mert az összes sor egyetlen eredményre összecsukható.

Csoportosítás egy vagy több mező szerint

Sorokat csoportosíthat egy vagy több oszlop szerint, és csoportonként aggregátumokat ad vissza.

Táblaséma

CREATE TABLE sales (
    id INT PRIMARY KEY,
    year INT,
    category NVARCHAR(50),
    revenue DECIMAL(10,2),
    quantity INT
);

GraphQL-lekérdezés

{
  sales(
    groupBy: { fields: ["year", "category"] }
  ) {
    items {
      year
      category
    }
    aggregates {
      revenue {
        sum
        average
      }
      quantity {
        sum
      }
    }
  }
}

Generált 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-válasz

{
  "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 }
        ]
      }
    }
  }
}

A válasz ugyanabban a sorrendben adja vissza a tömböket items és az összesítéseket, így a csoportokat az összesített értékekhez igazíthatja.

AZ összesített eredmények szűrése

Csoportok szűrésére használható having az összesítés után. Ez egyenértékű az SQL záradékkal HAVING .

Táblaséma

CREATE TABLE products (
    id INT PRIMARY KEY,
    category NVARCHAR(50),
    price DECIMAL(10,2)
);

GraphQL-lekérdezés

{
  products(
    groupBy: { fields: ["category"] }
  ) {
    items { category }
    aggregates {
      price {
        sum(having: { gt: 10000 })
        average
      }
    }
  }
}

Generált 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-válasz

Csak azokat a kategóriákat adja vissza, amelyeknél az összeg meghaladja az 10000-et:

{
  "data": {
    "products": {
      "items": [
        { "category": "Electronics" },
        { "category": "Furniture" }
      ],
      "aggregates": {
        "price": [
          { "sum": 15000.00, "average": 300.00 },
          { "sum": 12000.00, "average": 400.00 }
        ]
      }
    }
  }
}

HAVING operátorok

Operator SQL-ekvivalens 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 }

Megjegyzés:

Az egyes having szűrők egymástól függetlenül alkalmazhatók az összesítő függvényre. Egy GraphQL-lekérdezésben nem hozhat létre olyan összetett feltételeket, mint például "összeg > 1000 VAGY darabszám < 10".

DISTINCT az összesítésekben

Számold meg az egyedi értékeket a distinct: true.

Táblaséma

CREATE TABLE orders (
    id INT PRIMARY KEY,
    customer_id INT,
    product_id INT
);

GraphQL-lekérdezés

{
  orders(
    groupBy: { fields: ["customer_id"] }
  ) {
    items { customer_id }
    aggregates {
      product_id {
        count(distinct: true)
        count
      }
    }
  }
}

Generált 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-válasz

{
  "data": {
    "orders": {
      "items": [
        { "customer_id": 101 },
        { "customer_id": 102 }
      ],
      "aggregates": {
        "product_id": [
          { "count": 5 },
          { "count": 3 }
        ]
      }
    }
  }
}

Az első count (a distinct: true) ügyfelenként egyedi termékeket ad vissza. A második count az összes rendelést adja vissza.

Megjegyzés:

Ha több aggregátumot kér ugyanazon a mezőn, a DAB a kért sorrendben adja vissza őket. Aliasokkal (például uniqueProducts: count(distinct: true)) ön dokumentálhatja a válaszokat.

Szűrők kombinálása összesítéssel

Alkalmazza filter a csoportosítás előtti sorokra és having az összesítés utáni csoportokra. A műveletek sorrendjének megértése kritikus fontosságú:

  1. A szűrő (SQL WHERE) a csoportosítás előtt eltávolítja a sorokat
  2. Csoportosítás a fennmaradó sorok csoportokba gyűjtése
  3. Az összesítés csoportonként kiszámítja az összeget/átlagot/minimumot/maximumot/létszámot.
  4. A Having eltávolítja a feltételnek nem megfelelő csoportokat

GraphQL-lekérdezés

{
  sales(
    filter: { year: { gte: 2023 } }
    groupBy: { fields: ["region"] }
  ) {
    items { region }
    aggregates {
      revenue { sum average }
    }
  }
}

Generált 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

Jótanács

A sorok összesítés előtti kizárására használható filter . Csoportok szűrésére használható having az összesítés után.

Aliasok használata aggregációkkal

Értelmes mezőnevek létrehozása GraphQL-aliasok használatával.

{
  products(
    groupBy: { fields: ["category"] }
  ) {
    items { category }
    aggregates {
      price {
        totalRevenue: sum
        avgPrice: average
        cheapest: min
        mostExpensive: max
        productCount: count
      }
    }
  }
}

Sémabetekintés

Az introspection használatával megtekintheti, hogy mely összesítések érhetők el egy entitáshoz.

{
  __type(name: "BooksAggregates") {
    fields {
      name
      type { name }
    }
  }
}

Numerikus mezőket tesz elérhetővé sum, average, min, maxés count. Nem numerikus mezőket láthatóvá tesz count.

Tippek és korlátozások

  • Az összesítés és groupBy csak az SQL Server, az Azure SQL, a Microsoft Fabric SQL, és az Azure Synapse Dedikált SQL pool esetén alkalmazandó.
  • Az aggregátumok numerikus mezőkön futnak; count bármely mezőn működik. Számadatokat nem tartalmazó táblák csak a count-et jelenítik meg.
  • A csoportosítás ugyanazon entitás mezőire vonatkozik (nincs entitásközi csoportosítás).
  • A nagy aggregációk költségesek lehetnek; ha lehetséges, indexelje a groupBy oszlopokat és szűrje a sorokat a csoportosítás előtt.
  • A lekérdezési teljesítmény javítása érdekében hozzon létre indexeket a gyakran használt groupBy oszlopokon.

Hibaelhárítás

Hiba: A mező nem támogatja az összesítést

Ok: sum, average, min vagy max használata nem numerikus mezőn.

Solution

  • A mezőtípusok ellenőrzéséhez használja a sémabevezetést.
  • Nem numerikus mezőkhöz használható count .
  • Ellenőrizze a mezőleképezéseket, ha egyéni mezőneveket használ.

Hiba: Az összesítő csomópontok nem találhatók

Ok: Az entitásnak nincsenek numerikus oszlopai.

Solution

  • Ellenőrizze, hogy a táblaséma legalább egy numerikus oszlopot tartalmaz-e.
  • Szükség esetén használjon count aggregátumokat nem numerikus mezőkön.

Lassú összesítési lekérdezések

Ok: Nagy táblák megfelelő indexek nélkül.

Solution

  • Indexek létrehozása oszlopokon groupBy .
  • A sorok összesítés előtti korlátozására használható filter .
  • A visszaadott csoportok számának csökkentésére használható having .

Következő lépés