Adatok összesítése a GraphQL használatával

A Data API Builder támogatja a GraphQL-összesítést SQL Server családhoz és Azure Synapse Analytics dedikált SQL-készlet entitásaihoz. groupBy A gyűjtemény lekérdezésének mezője segítségével kiszámíthatja suma , avg, min, maxés count az értékeket.

A cikkben szereplő példák olvasási engedéllyel SQL Server és GraphQL-entitásokat használnak. A Data API Builder az egyes forgatókönyvekben látható utasításokhoz hasonlóan sql-t hoz létre. A paraméterértékek futásidőben lekérdezési paraméterekként jelennek meg. A sum, avg, minés max függvények numerikus mezőkre vonatkoznak. A count függvény bármely mezőn működik.

Important

Az összesítés nem érhető el Azure Cosmos DB NoSQL, PostgreSQL vagy MySQL esetén.

Az összesítés alapértelmezés szerint engedélyezve van. A kikapcsolásához állítsa a(z) enable-aggregation értékét false értékre a konfigurációs fájlban, a(z) runtime.graphql alatt. Az összesítő lekérdezések alapértelmezés szerint egy csoportlapot adnak vissza, alapértelmezés szerint 100-t. first A gyűjtemény lekérdezésének argumentumával módosíthatja például books(first: 500)a maximális értékeket. Állítsa be az alapértelmezett értéket a következővel runtime.pagination.default-page-size: .

GraphQL-séma hozzáadásai

Az összesítés engedélyezésekor a Data API Builder aggregációs mezőket és generált típusokat ad hozzá minden támogatott GraphQL-gyűjteményhez. A pontos generált típusnevek entitásspecifikusak és a GraphQL-bevezetőn keresztül láthatók, de a lekérdezés szintaxisa konzisztens az entitások között.

Az alábbi kódrészletek szintaxisformátumokat mutatnak, és nem teljes GraphQL-lekérdezéseket.

groupBy

A gyűjtemény csoportosított sorait adja vissza. Válassza ezt a tagot a(z) aggregációs lekérdezésben items helyett.

<collection> { groupBy { ... } }

groupBy(fields: [...])

Felsorolja a csoportosítandó entitásmezőket. Hagyja ki a(z) fields elemet, hogy az összes sort egyetlen csoportba vonja.

<collection> { groupBy(fields: [<field>, ...]) { ... } }

fields

Az összesítés eredményének minden egyes sorához tartozó csoportosított mezőértékeket adja vissza.

groupBy(fields: [<field>]) { fields { <field> } }

aggregations

Az egyes csoportok összesítő függvényeinek kijelöléseit tartalmazza.

groupBy { aggregations { <alias>: <function>(field: <field>) } }

sum, avg, minés max

Numerikus mezők összesítése.

aggregations { <alias>: sum(field: <numeric-field>) }
aggregations { <alias>: avg(field: <numeric-field>) }
aggregations { <alias>: min(field: <numeric-field>) }
aggregations { <alias>: max(field: <numeric-field>) }

count

Egy mező értékeinek megszámlálása.

aggregations { <alias>: count(field: <field>) }

field

Azonosítja az összesítendő entitásmezőt. A mezőnevek számértékek, nem sztringek.

<function>(field: <field>)

having

Szűri a csoportokat, miután a Data API Builder kiszámítja az összesített értéket.

aggregations { <alias>: <function>(field: <field>, having: { <operator>: <value> }) }

distinct

Megszámolja az egyedi értékeket, ha a(z) count elemmel használják.

aggregations { <alias>: count(field: <field>, distinct: true) }

A Data API Builder entitásspecifikus GraphQL-típusokat hoz létre ezek mögött a tagok mögött, beleértve a csoportsortípusokat, a csoportosított mezőtípusokat, az összesítő kijelölési típusokat, a mezőszámokat és having a bemeneti típusokat. Nem kell nevet adnia ezeknek a generált típusoknak egy lekérdezésben.

Samples

Az alábbi minták az SQL-táblát, a GraphQL-lekérdezést, az eredményül kapott SQL-t és a közös összesítési minták kimenetét mutatják.

Tábla összes sora összesítése

Ezt a mintát akkor használja, ha egy összegző sort szeretne a teljes entitáshoz.

SQL-tábla

CREATE TABLE dbo.Books (
    id INT NOT NULL PRIMARY KEY,
    title NVARCHAR(200) NOT NULL,
    [year] INT NOT NULL,
    pages INT NOT NULL
);

INSERT INTO dbo.Books (id, title, [year], pages) VALUES
    (1, N'GraphQL Basics', 2023, 120),
    (2, N'Advanced APIs', 2023, 450),
    (3, N'Data Patterns', 2023, 390),
    (4, N'Cloud APIs', 2024, 140),
    (5, N'Runtime Internals', 2024, 510),
    (6, N'Query Tuning', 2024, 250);
id title év pages
1 A GraphQL alapjai 2023 120
2 Speciális API-k 2023 450
3 Adatminták 2023 390
4 Felhőalapú API-k 2024 140
5 A futtatókörnyezet belső működése 2024 510
6 Lekérdezés finomhangolása 2024 250

GraphQL-lekérdezés

{
  books {
    groupBy {
      aggregations {
        totalPages: sum(field: pages)
        averagePages: avg(field: pages)
        shortestBook: min(field: pages)
        longestBook: max(field: pages)
        bookCount: count(field: id)
      }
    }
  }
}

Eredményként kapott SQL

SELECT TOP 100
    SUM([table0].[pages]) AS [totalPages],
    AVG([table0].[pages]) AS [averagePages],
    MIN([table0].[pages]) AS [shortestBook],
    MAX([table0].[pages]) AS [longestBook],
    COUNT([table0].[id]) AS [bookCount]
FROM [dbo].[Books] AS [table0]
WHERE 1 = 1
FOR JSON PATH, INCLUDE_NULL_VALUES;

Eredmény

{
  "data": {
    "books": {
      "groupBy": [
        {
          "aggregations": {
            "totalPages": 1860,
            "averagePages": 310,
            "shortestBook": 120,
            "longestBook": 510,
            "bookCount": 6
          }
        }
      ]
    }
  }
}
totalPages átlagos oldalszám shortestBook longestBook bookCount
1860 310 120 510 6

Sorok csoportosítása egy mező szerint

Mezőértékenként groupBy(fields: [...]) egy összesítő sort ad vissza. A mezőnevek GraphQL-számértékek, nem sztringek.

SQL-tábla

CREATE TABLE dbo.Books (
  id INT NOT NULL PRIMARY KEY,
  title NVARCHAR(200) NOT NULL,
  [year] INT NOT NULL,
  pages INT NOT NULL
);

INSERT INTO dbo.Books (id, title, [year], pages) VALUES
  (1, N'GraphQL Basics', 2023, 120),
  (2, N'Advanced APIs', 2023, 450),
  (3, N'Data Patterns', 2023, 390),
  (4, N'Cloud APIs', 2024, 140),
  (5, N'Runtime Internals', 2024, 510),
  (6, N'Query Tuning', 2024, 250);
id title év pages
1 A GraphQL alapjai 2023 120
2 Speciális API-k 2023 450
3 Adatminták 2023 390
4 Felhőalapú API-k 2024 140
5 A futtatókörnyezet belső felépítése 2024 510
6 Lekérdezés finomhangolása 2024 250

GraphQL-lekérdezés

{
  books(orderBy: { year: ASC }) {
    groupBy(fields: [year]) {
      fields { year }
      aggregations {
        totalPages: sum(field: pages)
        averagePages: avg(field: pages)
      }
    }
  }
}

Eredményként kapott SQL

SELECT TOP 100
    [table0].[year] AS [year],
    SUM([table0].[pages]) AS [totalPages],
    AVG([table0].[pages]) AS [averagePages]
FROM [dbo].[Books] AS [table0]
WHERE 1 = 1
GROUP BY [table0].[year]
ORDER BY [table0].[year] ASC
FOR JSON PATH, INCLUDE_NULL_VALUES;

Eredmény

{
  "data": {
    "books": {
      "groupBy": [
        {
          "fields": {
            "year": 2023
          },
          "aggregations": {
            "totalPages": 960,
            "averagePages": 320
          }
        },
        {
          "fields": {
            "year": 2024
          },
          "aggregations": {
            "totalPages": 900,
            "averagePages": 300
          }
        }
      ]
    }
  }
}
év totalPages átlagos oldalszám
2023 960 320
2024 900 300

Sorok csoportosítása a nézetből

Az aggregáció nézetalapú entitások esetében is működik. Konfiguráljon egy kulcsmezőt a nézethez, hogy a Data API Builder entitásként tegye elérhetővé.

SQL nézet

CREATE TABLE dbo.Employees (
  id INT NOT NULL PRIMARY KEY,
  name NVARCHAR(100) NOT NULL,
  department NVARCHAR(50) NOT NULL,
  title NVARCHAR(100) NOT NULL,
  age INT NOT NULL
);

INSERT INTO dbo.Employees (id, name, department, title, age) VALUES
  (1, N'Ada', N'Engineering', N'Developer', 29),
  (2, N'Ben', N'Engineering', N'Architect', 41),
  (3, N'Cora', N'Sales', N'Account manager', 34),
  (4, N'Diego', N'Sales', N'Sales lead', 52),
  (5, N'Ema', N'Support', N'Support engineer', 25),
  (6, N'Finn', N'Support', N'Support lead', 38),
  (7, N'Gia', N'Engineering', N'Engineering manager', 45);

CREATE VIEW dbo.EmployeeAgeReport
AS
SELECT id, department, age
FROM dbo.Employees;
id osztály életkor
1 Mérnöki tevékenységek 29
2 Mérnöki tevékenységek 41
3 Sales 34
4 Sales 52
5 Support 25
6 Support 38
7 Mérnöki tevékenységek 45

Konfigurálja a nézetet id kulcsmezőként:

dab add EmployeeAgeReport --source dbo.EmployeeAgeReport --source.type view --source.key-fields id --permissions "anonymous:read"

GraphQL-lekérdezés

{
  employeeAgeReports(orderBy: { department: ASC }) {
    groupBy(fields: [department]) {
      fields { department }
      aggregations {
        youngest: min(field: age)
        oldest: max(field: age)
        employeeCount: count(field: id)
      }
    }
  }
}

Eredményként kapott SQL

SELECT TOP 100
  [table0].[department] AS [department],
  MIN([table0].[age]) AS [youngest],
  MAX([table0].[age]) AS [oldest],
  COUNT([table0].[id]) AS [employeeCount]
FROM [dbo].[EmployeeAgeReport] AS [table0]
WHERE 1 = 1
GROUP BY [table0].[department]
ORDER BY [table0].[department] ASC
FOR JSON PATH, INCLUDE_NULL_VALUES;

Eredmény

{
  "data": {
    "employeeAgeReports": {
      "groupBy": [
        {
          "fields": {
            "department": "Engineering"
          },
          "aggregations": {
            "youngest": 29,
            "oldest": 45,
            "employeeCount": 3
          }
        },
        {
          "fields": {
            "department": "Sales"
          },
          "aggregations": {
            "youngest": 34,
            "oldest": 52,
            "employeeCount": 2
          }
        },
        {
          "fields": {
            "department": "Support"
          },
          "aggregations": {
            "youngest": 25,
            "oldest": 38,
            "employeeCount": 2
          }
        }
      ]
    }
  }
}
osztály legfiatalabb legrégebbi alkalmazottak száma
Mérnöki tevékenységek 29 45 3
Sales 34 52 2
Support 25 38 2

Sorok szűrése összesítés előtt

A filter gyűjtemény lekérdezésével korlátozhatja a forrássorokat, mielőtt a Data API Builder csoportosítja és összesíti őket.

SQL nézet

CREATE TABLE dbo.Employees (
  id INT NOT NULL PRIMARY KEY,
  name NVARCHAR(100) NOT NULL,
  department NVARCHAR(50) NOT NULL,
  title NVARCHAR(100) NOT NULL,
  age INT NOT NULL
);

INSERT INTO dbo.Employees (id, name, department, title, age) VALUES
  (1, N'Ada', N'Engineering', N'Developer', 29),
  (2, N'Ben', N'Engineering', N'Architect', 41),
  (3, N'Cora', N'Sales', N'Account manager', 34),
  (4, N'Diego', N'Sales', N'Sales lead', 52),
  (5, N'Ema', N'Support', N'Support engineer', 25),
  (6, N'Finn', N'Support', N'Support lead', 38),
  (7, N'Gia', N'Engineering', N'Engineering manager', 45);

CREATE VIEW dbo.EmployeeAgeReport
AS
SELECT id, department, age
FROM dbo.Employees;
id osztály életkor
1 Mérnöki tevékenységek 29
2 Mérnöki tevékenységek 41
3 Sales 34
4 Sales 52
5 Support 25
6 Support 38
7 Mérnöki tevékenységek 45

GraphQL-lekérdezés

{
  employeeAgeReports(filter: { age: { gt: 30 } }, orderBy: { department: ASC }) {
    groupBy(fields: [department]) {
      fields { department }
      aggregations {
        youngest: min(field: age)
        oldest: max(field: age)
        employeeCount: count(field: id)
      }
    }
  }
}

Eredményként kapott SQL

SELECT TOP 100
  [table0].[department] AS [department],
  MIN([table0].[age]) AS [youngest],
  MAX([table0].[age]) AS [oldest],
  COUNT([table0].[id]) AS [employeeCount]
FROM [dbo].[EmployeeAgeReport] AS [table0]
WHERE [table0].[age] > @param1
GROUP BY [table0].[department]
ORDER BY [table0].[department] ASC
FOR JSON PATH, INCLUDE_NULL_VALUES;

Ehhez a lekérdezéshez @param1 az .30

Eredmény

{
  "data": {
    "employeeAgeReports": {
      "groupBy": [
        {
          "fields": {
            "department": "Engineering"
          },
          "aggregations": {
            "youngest": 41,
            "oldest": 45,
            "employeeCount": 2
          }
        },
        {
          "fields": {
            "department": "Sales"
          },
          "aggregations": {
            "youngest": 34,
            "oldest": 52,
            "employeeCount": 2
          }
        },
        {
          "fields": {
            "department": "Support"
          },
          "aggregations": {
            "youngest": 38,
            "oldest": 38,
            "employeeCount": 1
          }
        }
      ]
    }
  }
}
osztály legfiatalabb legrégebbi employeeCount
Mérnöki tevékenységek 41 45 2
Sales 34 52 2
Support 38 38 1

Csoportok szűrése a következő használatával: having

Az összesítés utáni csoportszűréshez használja a(z) having elemet egy aggregátumfüggvénnyel. Ez a minta egy SQL-záradékra HAVING képeződik le.

SQL-tábla

CREATE TABLE dbo.Products (
    id INT NOT NULL PRIMARY KEY,
    category NVARCHAR(50) NOT NULL,
    price DECIMAL(10,2) NOT NULL
);

INSERT INTO dbo.Products (id, category, price) VALUES
    (1, N'Electronics', 5000.00),
    (2, N'Electronics', 10000.00),
    (3, N'Furniture', 4000.00),
    (4, N'Furniture', 8000.00),
    (5, N'Books', 100.00),
    (6, N'Books', 200.00);
id kategória ár
1 Elektronika 5000.00
2 Elektronika 10000.00
3 Bútor 4000.00
4 Bútor 8000.00
5 Könyvek 100,00
6 Könyvek 200,00

GraphQL-lekérdezés

{
  products(orderBy: { category: ASC }) {
    groupBy(fields: [category]) {
      fields { category }
      aggregations {
        totalValue: sum(field: price, having: { gt: 10000 })
        averagePrice: avg(field: price)
      }
    }
  }
}

Eredményként kapott SQL

SELECT TOP 100
    [table0].[category] AS [category],
    SUM([table0].[price]) AS [totalValue],
    AVG([table0].[price]) AS [averagePrice]
FROM [dbo].[Products] AS [table0]
WHERE 1 = 1
GROUP BY [table0].[category]
HAVING SUM([table0].[price]) > @param1
ORDER BY [table0].[category] ASC
FOR JSON PATH, INCLUDE_NULL_VALUES;

Ehhez a lekérdezéshez @param110000.

Eredmény

{
  "data": {
    "products": {
      "groupBy": [
        {
          "fields": {
            "category": "Electronics"
          },
          "aggregations": {
            "totalValue": 15000,
            "averagePrice": 7500
          }
        },
        {
          "fields": {
            "category": "Furniture"
          },
          "aggregations": {
            "totalValue": 12000,
            "averagePrice": 6000
          }
        }
      ]
    }
  }
}
kategória összérték átlagár
Elektronika 15000 7500
Bútor 12000 6000

Egyedi értékek megszámlálása

Használja a distinct: true elemet a count elemmel az egyes csoportok egyedi értékeinek megszámlálásához.

SQL-tábla

CREATE TABLE dbo.Orders (
    id INT NOT NULL PRIMARY KEY,
    customer_id INT NOT NULL,
    product_id INT NOT NULL
);

INSERT INTO dbo.Orders (id, customer_id, product_id) VALUES
    (1, 101, 1),
    (2, 101, 2),
    (3, 101, 2),
    (4, 101, 3),
    (5, 101, 4),
    (6, 101, 5),
    (7, 102, 1),
    (8, 102, 1),
    (9, 102, 2),
    (10, 102, 3);
id customer_id product_id
1 101 1
2 101 2
3 101 2
4 101 3
5 101 4
6 101 5
7 102 1
8 102 1
9 102 2
10 102 3

GraphQL-lekérdezés

{
  orders(orderBy: { customer_id: ASC }) {
    groupBy(fields: [customer_id]) {
      fields { customer_id }
      aggregations {
        uniqueProducts: count(field: product_id, distinct: true)
        totalOrders: count(field: id)
      }
    }
  }
}

Eredményként kapott SQL

SELECT TOP 100
    [table0].[customer_id] AS [customer_id],
    COUNT(DISTINCT ([table0].[product_id])) AS [uniqueProducts],
    COUNT([table0].[id]) AS [totalOrders]
FROM [dbo].[Orders] AS [table0]
WHERE 1 = 1
GROUP BY [table0].[customer_id]
ORDER BY [table0].[customer_id] ASC
FOR JSON PATH, INCLUDE_NULL_VALUES;

Eredmény

{
  "data": {
    "orders": {
      "groupBy": [
        {
          "fields": {
            "customer_id": 101
          },
          "aggregations": {
            "uniqueProducts": 5,
            "totalOrders": 6
          }
        },
        {
          "fields": {
            "customer_id": 102
          },
          "aggregations": {
            "uniqueProducts": 3,
            "totalOrders": 4
          }
        }
      ]
    }
  }
}
customer_id egyedi termékek Összes rendelés
101 5 6
102 3 4

Gyakori hibák

  • Válassza ki groupBy a gyűjteménymezőn belül. Ne adja át a(z) groupBy elemet gyűjtemény argumentumaként.
  • Használja aggregations, ne aggregates.
  • Használja avg, ne average.
  • Mezőszámértékek használata, például fields: [year]. Ne idézze a mezőneveket.
  • Ne válassza ki a(z) items és groupBy elemet ugyanabban a gyűjteménylekérdezésben.
  • Ha mezők szerint csoportosít, csak ugyanazokat a mezőket jelölje ki az fields objektumon belül.