Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
O Data API Builder (DAB) suporta agregação e agrupamento GraphQL para bases de dados da família SQL e Azure Synapse Analytics (pool SQL dedicado). As agregações permitem resumir campos numéricos e agrupar resultados sem precisar de escrever código API personalizado. Agregação e groupBy não estão disponíveis em Azure Cosmos DB para NoSQL, PostgreSQL ou MySQL.
Pré-requisitos
- Base de dados suportada:
- SQL Server 2016 ou posterior
- Base de Dados SQL do Azure
- Azure SQL Managed Instance
- Microsoft Fabric SQL
- Azure Synapse Analytics (Apenas pool SQL dedicado)
- CLI do construtor de API de dados. Instalar a CLI
- Um ficheiro de configuração DAB com a sua entidade exposta através do GraphQL.
- Um cliente GraphQL (por exemplo, Banana Cake Pop ou GraphQL Playground) para executar consultas.
Bases de dados suportadas
| Base de dados | Suporte à agregação |
|---|---|
| SQL Server / Azure SQL / Microsoft Fabric SQL | ✅ Sim |
| Azure Synapse (Dedicated SQL pool) | ✅ Sim |
| Azure Synapse (Serverless SQL pool) | ❌ Não |
| PostgreSQL | ❌ Não |
| MySQL | ❌ Não |
| Azure Cosmos DB for NoSQL | ❌ Não |
Funções agregadas
O DAB suporta as seguintes funções agregadas:
| Função | Aplica-se a | Description |
|---|---|---|
sum |
Apenas campos numéricos | Total de todos os valores |
average |
Apenas campos numéricos | Média de todos os valores |
min |
Apenas campos numéricos | Valor mínimo |
max |
Apenas campos numéricos | Valor máximo |
count |
Qualquer área | Contagem de valores não nulos |
Constraints
-
sum,average,min, emaxsó funcionam com tipos de dados numéricos (int, decimal, float, etc.). -
countFunciona em qualquer tipo de dado, incluindo cadeias e datas. - Se uma tabela não tiver colunas numéricas, o DAB não gera nós de agregação para essa entidade. Ainda podes usar
countem campos não numéricos.
Modificadores opcionais
| Modificador | Propósito | Example |
|---|---|---|
distinct: true |
Contar apenas valores únicos | Contar clientes distintos |
having: { ... } |
Grupos de filtros após agregação | Mostrar grupos com soma > inferior a 1000 |
Executar o runtime do DAB
Inicia o DAB com o teu ficheiro de configuração para que o endpoint GraphQL esteja disponível.
dab start
Resultados agregados de consulta
Esta secção apresenta um exemplo completo que mostra o esquema da tabela, consulta GraphQL, SQL gerado e resposta JSON.
Esquema da tabela
CREATE TABLE books (
id INT PRIMARY KEY,
title NVARCHAR(200),
year INT,
pages INT
);
Consulta GraphQL
Use o GraphQL para agrupar linhas e devolver valores agregados para campos numéricos.
{
books(
groupBy: { fields: ["year"] }
) {
items {
year
}
aggregates {
pages {
sum
average
min
max
}
}
}
}
-
groupBy.fieldsagrupa as linhas pelas colunas especificadas. -
aggregatesexpõe funções agregadas para campos numéricos (por exemplo,pages). - O esquema GraphQL apenas expõe agregados para campos que os suportam; Use a introspeção do esquema no seu cliente para confirmar campos e funções agregados disponíveis.
SQL Gerado
O DAB traduz a consulta GraphQL para 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
Resposta 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 }
]
}
}
}
}
Os items arrays e aggregates alinham-se por índice — o primeiro elemento em aggregates.pages corresponde ao primeiro grupo em items.
Agregar sem agrupar
Calcule agregados em todas as linhas ao omitir groupBy.
Consulta GraphQL
{
books {
aggregates {
pages {
sum
average
min
max
count
}
id {
count
}
}
}
}
SQL Gerado
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
Resposta JSON
{
"data": {
"books": {
"aggregates": {
"pages": {
"sum": 15420,
"average": 308,
"min": 120,
"max": 850,
"count": 50
},
"id": {
"count": 50
}
}
}
}
}
Sem groupBy, a resposta devolve um único objeto (não um array) porque todas as linhas colapsam num único resultado.
Agrupe por um ou mais campos
Agrupe as linhas por uma ou mais colunas e devolva os agregados por grupo.
Esquema da tabela
CREATE TABLE sales (
id INT PRIMARY KEY,
year INT,
category NVARCHAR(50),
revenue DECIMAL(10,2),
quantity INT
);
Consulta GraphQL
{
sales(
groupBy: { fields: ["year", "category"] }
) {
items {
year
category
}
aggregates {
revenue {
sum
average
}
quantity {
sum
}
}
}
}
SQL Gerado
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
Resposta 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 }
]
}
}
}
}
A resposta devolve arrays para items e agrega na mesma ordem, para que possas alinhar grupos com os seus valores agregados.
TER de filtrar resultados agregados
Use having para filtrar grupos após agregação. Isto é equivalente à cláusula do HAVING SQL.
Esquema da tabela
CREATE TABLE products (
id INT PRIMARY KEY,
category NVARCHAR(50),
price DECIMAL(10,2)
);
Consulta GraphQL
{
products(
groupBy: { fields: ["category"] }
) {
items { category }
aggregates {
price {
sum(having: { gt: 10000 })
average
}
}
}
}
SQL Gerado
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
Resposta JSON
Apenas as categorias em que a soma excede 10000 são devoltas:
{
"data": {
"products": {
"items": [
{ "category": "Electronics" },
{ "category": "Furniture" }
],
"aggregates": {
"price": [
{ "sum": 15000.00, "average": 300.00 },
{ "sum": 12000.00, "average": 400.00 }
]
}
}
}
}
Operadores 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 } |
Observação
Cada having filtro aplica-se independentemente à sua função agregada. Não podes criar condições de agregado cruzado como "somar > 1000 OU contar < 10" numa única consulta GraphQL.
DISTINCT em agregações
Contar valores únicos com distinct: true.
Esquema da tabela
CREATE TABLE orders (
id INT PRIMARY KEY,
customer_id INT,
product_id INT
);
Consulta GraphQL
{
orders(
groupBy: { fields: ["customer_id"] }
) {
items { customer_id }
aggregates {
product_id {
count(distinct: true)
count
}
}
}
}
SQL Gerado
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
Resposta JSON
{
"data": {
"orders": {
"items": [
{ "customer_id": 101 },
{ "customer_id": 102 }
],
"aggregates": {
"product_id": [
{ "count": 5 },
{ "count": 3 }
]
}
}
}
}
O primeiro count (com distinct: true) retorna produtos únicos por cliente. O segundo count retorna o total de encomendas.
Observação
Ao solicitar múltiplos agregados no mesmo campo, o DAB devolve-os na ordem solicitada. Use pseudónimos (por exemplo, uniqueProducts: count(distinct: true)) para tornar as respostas auto-documentadas.
Combinar filtros com agregação
Aplique filter às linhas antes de agrupar e having aos grupos após a agregação. Compreender a ordem das operações é fundamental:
-
Filter (SQL
WHERE) remove linhas antes de agrupar - Agrupar por recolhe as linhas restantes em grupos
- O agregado calcula a soma/média/mínimo/máximo/contagem por grupo
- Having remove grupos que não satisfazem a condição
Consulta GraphQL
{
sales(
filter: { year: { gte: 2023 } }
groupBy: { fields: ["region"] }
) {
items { region }
aggregates {
revenue { sum average }
}
}
}
SQL Gerado
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
Sugestão
Use filter para excluir linhas antes da agregação. Use having para filtrar grupos após agregação.
Usar pseudónimos com agregações
Crie nomes de campos significativos usando pseudónimos GraphQL.
{
products(
groupBy: { fields: ["category"] }
) {
items { category }
aggregates {
price {
totalRevenue: sum
avgPrice: average
cheapest: min
mostExpensive: max
productCount: count
}
}
}
}
Introspeção de esquemas
Use a introspeção para ver que agregados estão disponíveis para uma entidade.
{
__type(name: "BooksAggregates") {
fields {
name
type { name }
}
}
}
Campos numéricos expõem sum, average, min, max, e count. Campos não numéricos expõem count.
Dicas e limitações
- Agregação e
groupByaplicam-se apenas a SQL Server, Azure SQL, Microsoft Fabric SQL e Azure Synapse Dedicated SQL pool. - Os agregados executam-se em campos numéricos;
countFunciona em qualquer área. Tabelas sem colunas numéricas apenas expõemcount. - O agrupamento aplica-se a campos na mesma entidade (sem agrupamento entre entidades).
- Grandes agregações podem ser dispendiosas. Indexe as colunas GroupBy e filtre as linhas antes de agrupar, sempre que possível.
- Crie índices nas colunas frequentemente usadas
groupBypara melhorar o desempenho das consultas.
Solução de problemas
Erro: O campo não suporta agregação
Causa: Usando sum, average, min, ou max num campo não numérico.
Solução:
- Use a introspeção de esquemas para verificar os tipos de campo.
-
countUse para campos não numéricos. - Verifica os mapeamentos de campos se usares nomes de campo personalizados.
Erro: Não foram encontrados nós de agregação
Causa: A entidade não tem colunas numéricas.
Solução:
- O esquema da tabela de verificação tem pelo menos uma coluna numérica.
-
countUse agregados em campos não numéricos, se necessário.
Consultas de agregação lentas
Causa: Tabelas grandes sem índices adequados.
Solução:
- Crie índices em
groupBycolunas. - Use
filterpara limitar as linhas antes da agregação. - Use
havingpara reduzir o número de grupos devolvidos.