Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Nástroj Data API Builder podporuje agregaci GraphQL pro entity řady SQL Server a pro entity ve vyhrazeném fondu SQL služby Azure Synapse Analytics. Pomocí pole groupBy v dotazu kolekce můžete vypočítat hodnoty sum, avg, min, max a count.
Příklady v tomto článku používají entity SQL Server a GraphQL s oprávněním ke čtení. Tvůrce rozhraní DATA API generuje SQL stejně jako příkazy zobrazené v jednotlivých scénářích. Hodnoty parametrů se zobrazují jako parametry dotazu za běhu. Funkce sum, avg, min a max platí pro číselná pole. Funkce count funguje na libovolném poli.
Important
Agregace není dostupná pro Azure Cosmos DB pro NoSQL, PostgreSQL nebo MySQL.
Agregace je ve výchozím nastavení povolená. Chcete-li jej vypnout, nastavte v konfiguračním souboru v části runtime.graphql hodnotu enable-aggregation na false. Agregační dotazy vracejí jednu stránku skupin, ve výchozím nastavení 100. Pomocí argumentu first v dotazu kolekce změňte maximum, například books(first: 500). Nastavte výchozí hodnotu pomocí runtime.pagination.default-page-size.
Přidání schématu GraphQL
Když povolíte agregaci, Tvůrce rozhraní Data API přidá do každé podporované kolekce GraphQL agregační pole a vygenerované typy. Přesné vygenerované názvy typů jsou specifické pro entitu a viditelné prostřednictvím introspekce GraphQL, ale syntaxe dotazu je konzistentní napříč entitami.
Následující fragmenty kódu zobrazují formáty syntaxe, ne kompletní dotazy GraphQL.
groupBy
Vrátí seskupené řádky pro kolekci. Místo agregačního dotazu vyberte tohoto člena items .
<collection> { groupBy { ... } }
groupBy(fields: [...])
Zobrazí seznam polí entity, podle které se mají seskupit. Vynechte fields, aby se všechny řádky agregovaly do jedné skupiny.
<collection> { groupBy(fields: [<field>, ...]) { ... } }
fields
Vrátí seskupené hodnoty polí pro každý řádek ve výsledku agregace.
groupBy(fields: [<field>]) { fields { <field> } }
aggregations
Obsahuje výběr agregační funkce pro každou skupinu.
groupBy { aggregations { <alias>: <function>(field: <field>) } }
sum, avg, min a max
Agregovaná číselná pole
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
Spočítá hodnoty pro pole.
aggregations { <alias>: count(field: <field>) }
field
Identifikuje pole entity, které se má agregovat. Názvy polí jsou výčtové hodnoty, nikoli řetězce.
<function>(field: <field>)
having
Filtruje skupiny poté, co nástroj Data API builder vypočítá agregovanou hodnotu.
aggregations { <alias>: <function>(field: <field>, having: { <operator>: <value> }) }
distinct
Počítá jedinečné hodnoty při použití s count.
aggregations { <alias>: count(field: <field>, distinct: true) }
Tvůrce rozhraní Data API generuje pro tyto členy typy GraphQL specifické pro jednotlivé entity, včetně typů řádků skupin, seskupených typů polí, typů pro výběr agregací, výčtů polí a vstupních typů having. Tyto vygenerované typy nemusíte v dotazu pojmenovat.
Samples
Následující ukázky ukazují tabulku SQL, dotaz GraphQL, výsledný sql a výsledný výstup pro běžné agregační vzory.
Agregace všech řádků v tabulce
Tento vzor použijte, pokud chcete mít jeden souhrnný řádek pro celou entitu.
Tabulka SQL
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 | rok | stránky |
|---|---|---|---|
| 1 | Základy GraphQL | 2023 | 120 |
| 2 | Pokročilá rozhraní API | 2023 | 450 |
| 3 | Vzory dat | 2023 | 390 |
| 4 | Cloudová rozhraní API | 2024 | 140 |
| 5 | Interní informace o modulu runtime | 2024 | 510 |
| 6 | Ladění dotazů | 2024 | 250 |
Dotaz GraphQL
{
books {
groupBy {
aggregations {
totalPages: sum(field: pages)
averagePages: avg(field: pages)
shortestBook: min(field: pages)
longestBook: max(field: pages)
bookCount: count(field: id)
}
}
}
}
Výsledný 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;
Výsledný výstup
{
"data": {
"books": {
"groupBy": [
{
"aggregations": {
"totalPages": 1860,
"averagePages": 310,
"shortestBook": 120,
"longestBook": 510,
"bookCount": 6
}
}
]
}
}
}
| Celkový počet stránek | průměrný počet stránek | nejkratší kniha | Nejdelší kniha | bookCount |
|---|---|---|---|---|
| 1860 | 310 | 120 | 510 | 6 |
Seskupení řádků podle jednoho pole
Pomocí groupBy(fields: [...]) vrátíte jeden agregovaný řádek pro každou hodnotu pole. Názvy polí jsou hodnoty výčtu GraphQL, nikoli řetězce.
Tabulka SQL
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 | rok | stránky |
|---|---|---|---|
| 1 | Základy GraphQL | 2023 | 120 |
| 2 | Pokročilá rozhraní API | 2023 | 450 |
| 3 | Vzory dat | 2023 | 390 |
| 4 | Cloudová rozhraní API | 2024 | 140 |
| 5 | Interní informace o modulu runtime | 2024 | 510 |
| 6 | Ladění dotazů | 2024 | 250 |
Dotaz GraphQL
{
books(orderBy: { year: ASC }) {
groupBy(fields: [year]) {
fields { year }
aggregations {
totalPages: sum(field: pages)
averagePages: avg(field: pages)
}
}
}
}
Výsledný příkaz 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;
Výsledný výstup
{
"data": {
"books": {
"groupBy": [
{
"fields": {
"year": 2023
},
"aggregations": {
"totalPages": 960,
"averagePages": 320
}
},
{
"fields": {
"year": 2024
},
"aggregations": {
"totalPages": 900,
"averagePages": 300
}
}
]
}
}
}
| rok | celkový počet stran | průměrný počet stránek |
|---|---|---|
| 2023 | 960 | 320 |
| 2024 | 900 | 300 |
Seskupit řádky v zobrazení
Agregace také funguje pro entity založené na zobrazení. Nakonfigurujte pole klíče pro zobrazení, aby ho tvůrce rozhraní Data API mohl vystavit jako entitu.
Zobrazení SQL
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 | oddělení | věk |
|---|---|---|
| 1 | Inženýrství | 29 |
| 2 | Inženýrství | 41 |
| 3 | Sales | 34 |
| 4 | Sales | 52 |
| 5 | Support | 25 |
| 6 | Support | 38 |
| 7 | Inženýrství | 45 |
Nakonfigurujte zobrazení s id jako klíčovým polem:
dab add EmployeeAgeReport --source dbo.EmployeeAgeReport --source.type view --source.key-fields id --permissions "anonymous:read"
Dotaz GraphQL
{
employeeAgeReports(orderBy: { department: ASC }) {
groupBy(fields: [department]) {
fields { department }
aggregations {
youngest: min(field: age)
oldest: max(field: age)
employeeCount: count(field: id)
}
}
}
}
Výsledný dotaz 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;
Výsledný výstup
{
"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
}
}
]
}
}
}
| oddělení | Nejmladší | nejstarší | počet zaměstnanců |
|---|---|---|---|
| Inženýrství | 29 | 45 | 3 |
| Sales | 34 | 52 | 2 |
| Support | 25 | 38 | 2 |
Filtrování řádků před agregací
Pomocí filter u dotazu na kolekci můžete omezit zdrojové řádky předtím, než je Data API builder seskupí a agreguje.
Zobrazení SQL
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 | oddělení | věk |
|---|---|---|
| 1 | Inženýrství | 29 |
| 2 | Inženýrství | 41 |
| 3 | Sales | 34 |
| 4 | Sales | 52 |
| 5 | Support | 25 |
| 6 | Support | 38 |
| 7 | Inženýrství | 45 |
Dotaz GraphQL
{
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)
}
}
}
}
Výsledný příkaz 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;
Pro tento dotaz platí, že @param1 je 30.
Výsledný výstup
{
"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
}
}
]
}
}
}
| oddělení | nejmladší | Nejstarší | počet zaměstnanců |
|---|---|---|---|
| Inženýrství | 41 | 45 | 2 |
| Sales | 34 | 52 | 2 |
| Support | 38 | 38 | 1 |
Filtrování skupin pomocí having
Používá se having u agregační funkce k filtrování skupin po agregaci. Tento vzor se mapuje na klauzuli SQL HAVING .
Tabulka SQL
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 | kategorie | cena |
|---|---|---|
| 1 | Elektronika | 5000.00 |
| 2 | Elektronika | 10000.00 |
| 3 | Nábytek | 4000.00 |
| 4 | Nábytek | 8000.00 |
| 5 | Knihy | 100.00 |
| 6 | Knihy | 200.00 |
Dotaz GraphQL
{
products(orderBy: { category: ASC }) {
groupBy(fields: [category]) {
fields { category }
aggregations {
totalValue: sum(field: price, having: { gt: 10000 })
averagePrice: avg(field: price)
}
}
}
}
Výsledný dotaz 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;
Pro tento dotaz je @param110000.
Výsledný výstup
{
"data": {
"products": {
"groupBy": [
{
"fields": {
"category": "Electronics"
},
"aggregations": {
"totalValue": 15000,
"averagePrice": 7500
}
},
{
"fields": {
"category": "Furniture"
},
"aggregations": {
"totalValue": 12000,
"averagePrice": 6000
}
}
]
}
}
}
| kategorie | celková hodnota | průměrná cena |
|---|---|---|
| Elektronika | 15000 | 7500 |
| Nábytek | 12000 | 6000 |
Počet jedinečných hodnot
Použijte distinct: true spolu s count k počítání unikátních hodnot v každé skupině.
Tabulka SQL
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 |
Dotaz GraphQL
{
orders(orderBy: { customer_id: ASC }) {
groupBy(fields: [customer_id]) {
fields { customer_id }
aggregations {
uniqueProducts: count(field: product_id, distinct: true)
totalOrders: count(field: id)
}
}
}
}
Výsledný příkaz 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;
Výsledný výstup
{
"data": {
"orders": {
"groupBy": [
{
"fields": {
"customer_id": 101
},
"aggregations": {
"uniqueProducts": 5,
"totalOrders": 6
}
},
{
"fields": {
"customer_id": 102
},
"aggregations": {
"uniqueProducts": 3,
"totalOrders": 4
}
}
]
}
}
}
| customer_id | uniqueProducts | Celkový počet objednávek |
|---|---|---|
| 101 | 5 | 6 |
| 102 | 3 | 4 |
Běžné chyby
- Vyberte
groupByv poli kolekce. NepředávejtegroupByjako argument kolekce. - Použít
aggregations, neaggregates. - Použít
avg, neaverage. - Použijte hodnoty výčtu polí, například
fields: [year]. Názvy polí neuvádějte v uvozovkách. - Nevybírejte
itemsagroupByve stejném dotazu kolekce. - Při seskupení podle polí vyberte pouze stejná pole uvnitř objektu
fields.