Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Il generatore di API dati supporta l'aggregazione GraphQL e il raggruppamento per i database della famiglia SQL e Azure Synapse Analytics (pool SQL dedicato). Le aggregazioni consentono di riepilogare i campi numerici e i risultati del gruppo senza scrivere codice API personalizzato. Aggregazione e groupBy non sono disponibili per Azure Cosmos DB per NoSQL, PostgreSQL o MySQL.
Prerequisiti
- Database supportati:
- SQL Server 2016 o versione successiva
- Database SQL di Microsoft Azure
- Istanza SQL gestita di Azure
- Microsoft Fabric SQL
- Azure Synapse Analytics (solo pool SQL dedicato)
- CLI generatore di API dati. Installare l'interfaccia della riga di comando
- Un file di configurazione DAB con l'entità esposta tramite GraphQL.
- Un client GraphQL ,ad esempio Banana Cake Pop o GraphQL Playground, per eseguire query.
Database supportati
| Banca dati | Supporto delle aggregazioni |
|---|---|
| SQL Server/Azure SQL/Microsoft Fabric SQL | ✅ Sì |
| Azure Synapse (pool SQL dedicato) | ✅ Sì |
| Azure Synapse (pool SQL senza server) | ❌ No |
| PostgreSQL | ❌ No |
| MySQL | ❌ No |
| Azure Cosmos DB per il NoSQL | ❌ No |
Funzioni di aggregazione
DAB supporta le funzioni di aggregazione seguenti:
| Funzione | Si applica a: | Description |
|---|---|---|
sum |
Solo campi numerici | Totale di tutti i valori |
average |
Solo campi numerici | Media di tutti i valori |
min |
Solo campi numerici | Valore minimo |
max |
Solo campi numerici | Valore massimo |
count |
Qualsiasi campo | Numero di valori non Null |
Constraints
-
sum,average,minemaxfunzionano solo sui tipi di dati numerici (int, decimal, float e così via). -
countfunziona su qualsiasi tipo di dati, incluse stringhe e date. - Se una tabella non contiene colonne numeriche, DAB non genera nodi di aggregazione per tale entità. È comunque possibile usare
countin campi non numerici.
Modificatori facoltativi
| Modificatore | Scopo | Example |
|---|---|---|
distinct: true |
Conteggia solo valori univoci | Contare i clienti distinti |
having: { ... } |
Filtrare i gruppi dopo l'aggregazione | Mostra gruppi con somma > 1000 |
Avviare il runtime DAB
Avviare DAB con il file di configurazione in modo che sia disponibile l'endpoint GraphQL.
dab start
Interrogare i risultati aggregati
Questa sezione illustra un esempio completo che illustra lo schema della tabella, la query GraphQL, la risposta SQL generata e JSON.
Schema tabella
CREATE TABLE books (
id INT PRIMARY KEY,
title NVARCHAR(200),
year INT,
pages INT
);
Query GraphQL
Usare GraphQL per raggruppare le righe e restituire valori aggregati per i campi numerici.
{
books(
groupBy: { fields: ["year"] }
) {
items {
year
}
aggregates {
pages {
sum
average
min
max
}
}
}
}
-
groupBy.fieldsraggruppa le righe in base alle colonne specificate. -
aggregatesespone le funzioni di aggregazione per i campi numerici , ad esempiopages. - Lo schema GraphQL espone solo le aggregazioni per i campi che li supportano; usare l'introspezione dello schema nel client per confermare i campi e le funzioni aggregati disponibili.
SQL generato
DAB converte la query GraphQL 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
Risposta JSON
{
"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 }
]
}
}
}
}
Le items matrici e aggregates sono allineate in base all'indice: il primo elemento in aggregates.pages corrisponde al primo gruppo in items.
Aggregazione senza raggruppamento
Calcolare le aggregazioni in tutte le righe quando si omette groupBy.
Query GraphQL
{
books {
aggregates {
pages {
sum
average
min
max
count
}
id {
count
}
}
}
}
SQL generato
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
Risposta JSON
{
"data": {
"books": {
"aggregates": {
"pages": {
"sum": 15420,
"average": 308,
"min": 120,
"max": 850,
"count": 50
},
"id": {
"count": 50
}
}
}
}
}
Senza groupBy, la risposta restituisce un singolo oggetto (non una matrice) perché tutte le righe vengono compresse in un unico risultato.
Raggruppare uno o più campi
Raggruppare le righe in base a una o più colonne e restituire aggregazioni per gruppo.
Schema tabella
CREATE TABLE sales (
id INT PRIMARY KEY,
year INT,
category NVARCHAR(50),
revenue DECIMAL(10,2),
quantity INT
);
Query GraphQL
{
sales(
groupBy: { fields: ["year", "category"] }
) {
items {
year
category
}
aggregates {
revenue {
sum
average
}
quantity {
sum
}
}
}
}
SQL generato
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
Risposta JSON
{
"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 }
]
}
}
}
}
La risposta restituisce matrici per items e aggregazioni nello stesso ordine, in modo da poter allineare i gruppi ai valori aggregati.
Essere obbligati a filtrare i risultati aggregati
Usare having per filtrare i gruppi dopo l'aggregazione. Equivale alla clausola di HAVING SQL.
Schema tabella
CREATE TABLE products (
id INT PRIMARY KEY,
category NVARCHAR(50),
price DECIMAL(10,2)
);
Query GraphQL
{
products(
groupBy: { fields: ["category"] }
) {
items { category }
aggregates {
price {
sum(having: { gt: 10000 })
average
}
}
}
}
SQL generato
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
Risposta JSON
Vengono restituite solo le categorie in cui la somma supera 10000:
{
"data": {
"products": {
"items": [
{ "category": "Electronics" },
{ "category": "Furniture" }
],
"aggregates": {
"price": [
{ "sum": 15000.00, "average": 300.00 },
{ "sum": 12000.00, "average": 400.00 }
]
}
}
}
}
Operatori HAVING
| Operator | Equivalente SQL | 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 } |
Annotazioni
Ogni having filtro si applica in modo indipendente alla funzione di aggregazione. Non è possibile creare condizioni di aggregazione incrociata come "sum > 1000 OR count < 10" in una singola query GraphQL.
DISTINCT nelle aggregazioni
Contare i valori univoci con distinct: true.
Schema tabella
CREATE TABLE orders (
id INT PRIMARY KEY,
customer_id INT,
product_id INT
);
Query GraphQL
{
orders(
groupBy: { fields: ["customer_id"] }
) {
items { customer_id }
aggregates {
product_id {
count(distinct: true)
count
}
}
}
}
SQL generato
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
Risposta JSON
{
"data": {
"orders": {
"items": [
{ "customer_id": 101 },
{ "customer_id": 102 }
],
"aggregates": {
"product_id": [
{ "count": 5 },
{ "count": 3 }
]
}
}
}
}
Il primo count (con distinct: true) restituisce prodotti univoci per cliente. Il secondo count restituisce gli ordini totali.
Annotazioni
Quando si richiedono più aggregazioni nello stesso campo, DAB le restituisce nell'ordine richiesto. Usare alias (ad esempio, uniqueProducts: count(distinct: true)) per rendere le risposte auto-documentanti.
Combinare i filtri con l'aggregazione
Applicare filter alle righe prima del raggruppamento e having ai gruppi dopo l'aggregazione. Comprendere l'ordine delle operazioni è fondamentale:
-
Filtro (SQL
WHERE) rimuove le righe prima del raggruppamento - Raggruppa per raccoglie le righe rimanenti in gruppi
- Aggrega calcola somma/media/min/max/conteggio per gruppo
- Having rimuove i gruppi che non soddisfano la condizione
Query GraphQL
{
sales(
filter: { year: { gte: 2023 } }
groupBy: { fields: ["region"] }
) {
items { region }
aggregates {
revenue { sum average }
}
}
}
SQL generato
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
Suggerimento
Usare filter per escludere righe prima dell'aggregazione. Usare having per filtrare i gruppi dopo l'aggregazione.
Usare gli alias con le aggregazioni
Creare nomi di campo significativi usando gli alias GraphQL.
{
products(
groupBy: { fields: ["category"] }
) {
items { category }
aggregates {
price {
totalRevenue: sum
avgPrice: average
cheapest: min
mostExpensive: max
productCount: count
}
}
}
}
Introspezione dello schema
Usare l'introspezione per vedere quali aggregazioni sono disponibili per un'entità.
{
__type(name: "BooksAggregates") {
fields {
name
type { name }
}
}
}
I campi numerici espongono sum, averagemin, max, e count. I campi non numerici espongono count.
Suggerimenti e limitazioni
- Aggregazione e
groupBysi applicano solo a SQL Server, Azure SQL, Microsoft Fabric SQL e Azure Synapse Dedicated SQL pool. - Le aggregazioni vengono eseguite su campi numerici;
countfunziona su qualsiasi campo. Le tabelle senza colonne numeriche mostrano solocount. - Il raggruppamento si applica ai campi della stessa entità (nessun gruppo tra entitàBy).
- Le aggregazioni di grandi dimensioni possono essere costose; indicizzare le colonne groupBy e filtrare le righe prima di raggrupparle, quando possibile.
- Creare indici sulle colonne
groupByutilizzate frequentemente per migliorare le prestazioni delle query.
Risoluzione dei problemi
Errore: Il campo non supporta l'aggregazione
Causa: uso di sum, averagemin, o max in un campo non numerico.
Soluzione:
- Usare l'introspezione dello schema per verificare i tipi di campo.
- Utilizzare
countper i campi non numerici. - Controlla i mapping dei campi se usi nomi di campi personalizzati.
Errore: Nodi di aggregazione non trovati
Causa: l'entità non ha colonne numeriche.
Soluzione:
- Verificare che lo schema della tabella contenga almeno una colonna numerica.
- Usare
countle aggregazioni nei campi non numerici, se necessario.
Query di aggregazione lente
Causa: tabelle di grandi dimensioni senza indici appropriati.
Soluzione:
- Creare indici su colonne
groupBy. - Usare
filterper limitare le righe prima dell'aggregazione. - Usare
havingper ridurre il numero di gruppi restituiti.