Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
O DAB (Construtor de API de Dados) dá suporte à agregação e ao agrupamento do GraphQL para bancos de dados da família SQL e do Azure Synapse Analytics (pool de SQL dedicado). As agregações permitem resumir campos numéricos e resultados de grupo sem escrever código de API personalizado. A agregação e groupBy não estão disponíveis para o Azure Cosmos DB para NoSQL, PostgreSQL ou MySQL.
Pré-requisitos
- Banco de dados com suporte:
- SQL Server 2016 ou posterior
- Banco de Dados SQL do Azure
- Instância Gerenciada de SQL do Azure
- Microsoft Fabric SQL
- Azure Synapse Analytics (somente pool de SQL dedicado)
- CLI do construtor de API de Dados. Instalar a CLI
- Um arquivo de configuração do DAB onde sua entidade é exposta por meio do GraphQL.
- Um cliente GraphQL (por exemplo, Banana Cake Pop ou GraphQL Playground) para executar consultas.
Bancos de dados com suporte
| Base de dados | Suporte à agregação |
|---|---|
| SQL Server/SQL do Azure/MICROSOFT Fabric SQL | ✅ Sim |
| Azure Synapse (pool de SQL dedicado) | ✅ Sim |
| Azure Synapse (pool de SQL sem servidor) | ❌ Não |
| PostgreSQL | ❌ Não |
| MySQL | ❌ Não |
| Azure Cosmos DB for NoSQL | ❌ Não |
Funções de agregação
O DAB dá suporte às seguintes funções de agregação:
| Função | Aplica-se a | Description |
|---|---|---|
sum |
Somente campos numéricos | Total de todos os valores |
average |
Somente campos numéricos | Média de todos os valores |
min |
Somente campos numéricos | Valor mínimo |
max |
Somente campos numéricos | Valor máximo |
count |
Qualquer campo | Contagem de valores não nulos |
Constraints
-
sum,averageeminmaxsó funcionam em tipos de dados numéricos (int, decimal, float etc.). -
countfunciona em qualquer tipo de dados, incluindo cadeias de caracteres e datas. - Se uma tabela não tiver colunas numéricas, o DAB não gerará nós de agregação para essa entidade. Você ainda pode usar
countem campos não numéricos.
Modificadores opcionais
| Modificador | Propósito | Example |
|---|---|---|
distinct: true |
Contar somente valores únicos | Contar clientes distintos |
having: { ... } |
Filtrar grupos após a agregação | Mostrar grupos com a soma > de 1000 |
Executar o runtime do DAB
Inicie o DAB com o arquivo de configuração para que o endpoint GraphQL esteja disponível.
dab start
Consultar resultados agregados
Esta seção apresenta um exemplo completo mostrando o esquema de tabela, a consulta GraphQL, o SQL gerado e a resposta JSON.
Esquema de tabela
CREATE TABLE books (
id INT PRIMARY KEY,
title NVARCHAR(200),
year INT,
pages INT
);
Consulta GraphQL
Use o GraphQL para agrupar linhas e retornar valores agregados para campos numéricos.
{
books(
groupBy: { fields: ["year"] }
) {
items {
year
}
aggregates {
pages {
sum
average
min
max
}
}
}
}
-
groupBy.fieldsagrupa linhas pelas colunas especificadas. -
aggregatesexpõe funções de agregação para campos numéricos (por exemplo,pages). - O esquema GraphQL expõe apenas agregações para campos que dão suporte a eles; use a introspecção de esquema em seu cliente para confirmar campos e funções de agregação disponíveis.
SQL gerado
O DAB converte a consulta GraphQL em 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 arrays items e aggregates estão alinhados por índice — o primeiro elemento em aggregates.pages corresponde ao primeiro grupo em items.
Agregar sem agrupamento
Calcular agregações em todas as linhas quando você 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 retorna um único objeto (não uma matriz) porque todas as linhas são recolhidas em um único resultado.
Agrupar por um ou mais campos
Agrupar linhas por uma ou mais colunas e retornar agregações por grupo.
Esquema de 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 retorna matrizes para items e valores agregados na mesma ordem, para que você possa alinhar os grupos com seus valores agregados.
TER que filtrar resultados agregados
Use having para filtrar grupos após a agregação. Isso é equivalente à cláusula do HAVING SQL.
Esquema de 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
Somente as categorias em que a soma excede 10000 são retornadas:
{
"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 a 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 se aplica de forma independente à sua função de agregação. Você não pode criar condições de agregação cruzada, como "soma > 1000 OU contagem < 10" em uma única consulta GraphQL.
DISTINCT em agregações
Contar valores exclusivos com distinct: true.
Esquema de 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 exclusivos por cliente. O segundo count retorna o total de pedidos.
Observação
Ao solicitar várias agregações no mesmo campo, o DAB as retorna na ordem solicitada. Use aliases (por exemplo, uniqueProducts: count(distinct: true)) para tornar as respostas autoexplicativas.
Combinar filtros com agregação
Aplique filter às linhas antes do agrupamento e having aos grupos após a agregação. Entender a ordem das operações é fundamental:
-
Filtro (SQL
WHERE) remove linhas antes do agrupamento - Agrupar organiza as linhas restantes em grupos
- Agregar calcula soma/média/mínimo/máximo/contagem por grupo
- HAVING remove grupos que não correspondem à 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
Dica
Use filter para excluir linhas antes da agregação. Use having para filtrar grupos após a agregação.
Usar aliases com agregações
Crie nomes de campo significativos usando aliases do GraphQL.
{
products(
groupBy: { fields: ["category"] }
) {
items { category }
aggregates {
price {
totalRevenue: sum
avgPrice: average
cheapest: min
mostExpensive: max
productCount: count
}
}
}
}
Introspecção de esquema
Use a introspecção para ver quais agregações estão disponíveis para uma entidade.
{
__type(name: "BooksAggregates") {
fields {
name
type { name }
}
}
}
Campos numéricos expõem sum, average, min, maxe count. Campos não numéricos revelam count.
Dicas e limitações
- Agregação e
groupByse aplicam apenas ao SQL Server, ao Azure SQL, ao Microsoft Fabric SQL e ao pool de SQL Dedicado do Azure Synapse. - Agregações são executadas em campos numéricos;
countfunciona em qualquer campo. Tabelas sem colunas numéricas expõem apenascount. - O agrupamento se aplica a campos na mesma entidade (sem groupBy entre entidades).
- Agregações grandes podem ser caras; indexe as colunas que você utiliza no groupBy e filtre linhas antes de agrupar quando possível.
- Crie índices em colunas usadas
groupBycom frequência para melhorar o desempenho da consulta.
Resolução de problemas
Erro: o campo não dá suporte à agregação
Causa: usando sum, average, minou max em um campo não numérico.
Solução:
- Use a introspecção de esquema para verificar os tipos de campo.
- Use
countpara campos não numéricos. - Verifique os mapeamentos de campo se estiver usando nomes de campo personalizados.
Erro: nós de agregação não encontrados
Causa: a entidade não tem colunas numéricas.
Solução:
- Verifique se o esquema da tabela tem pelo menos uma coluna numérica.
- Utilize
countagregações 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 linhas antes da agregação. - Use
havingpara reduzir o número de grupos retornados.