Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Data API Builder admite la agregación de GraphQL para las entidades de la familia SQL Server y del grupo de SQL dedicado de Azure Synapse Analytics. Utilice el campo groupBy en una consulta de colección para calcular los valores sum, avg, min, max y count.
En los ejemplos de este artículo se usan entidades SQL Server y GraphQL con permiso de lectura. Data API builder genera instrucciones SQL como las que se muestran en cada escenario. Los valores de parámetro aparecen como parámetros de consulta en tiempo de ejecución. Las sumfunciones , avg, miny max se aplican a los campos numéricos. La count función funciona en cualquier campo.
Importante
La agregación no está disponible para Azure Cosmos DB para NoSQL, PostgreSQL o MySQL.
La agregación está habilitada de forma predeterminada. Para desactivarlo, configure enable-aggregation como false debajo de runtime.graphql en el archivo de configuración. Las consultas de agregación devuelven una página de grupos, 100 de forma predeterminada. Use el first argumento de la consulta de colección para cambiar el máximo, por ejemplo books(first: 500). Establezca el valor predeterminado con runtime.pagination.default-page-size.
Adiciones de esquema de GraphQL
Al habilitar la agregación, data API Builder agrega campos de agregación y tipos generados a cada colección de GraphQL admitida. Los nombres de tipo generados exactos son específicos de la entidad y son visibles a través de la introspección de GraphQL, pero la sintaxis de consulta es coherente entre entidades.
En los fragmentos de código siguientes se muestran formatos de sintaxis, no se completan las consultas de GraphQL.
groupBy
Devuelve filas agrupadas para la colección. Seleccione este miembro en lugar de items en una consulta de agregación.
<collection> { groupBy { ... } }
groupBy(fields: [...])
Enumera los campos de entidad por los que se va a agrupar. Omitir fields para agregar todas las filas a un grupo.
<collection> { groupBy(fields: [<field>, ...]) { ... } }
fields
Devuelve los valores de campo agrupados para cada fila del resultado de agregación.
groupBy(fields: [<field>]) { fields { <field> } }
aggregations
Contiene la selección de funciones de agregación para cada grupo.
groupBy { aggregations { <alias>: <function>(field: <field>) } }
sum, avg, min y max.
Agregar campos numéricos.
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
Cuenta los valores de un campo.
aggregations { <alias>: count(field: <field>) }
field
Identifica el campo de la entidad que se va a usar para la agregación. Los nombres de campo son valores de enumeración, no cadenas.
<function>(field: <field>)
having
Filtra los grupos después de que Data API Builder calcule el valor agregado.
aggregations { <alias>: <function>(field: <field>, having: { <operator>: <value> }) }
distinct
Cuenta valores únicos cuando se utiliza con count.
aggregations { <alias>: count(field: <field>, distinct: true) }
Data API builder genera tipos GraphQL específicos de la entidad para estos miembros, incluidos tipos de fila agrupada, tipos de campo agrupado, tipos de selección de agregados, enumeraciones de campo y tipos de entrada having. No es necesario asignar un nombre a esos tipos generados en una consulta.
Samples
Los siguientes ejemplos muestran la tabla SQL, la consulta GraphQL, el SQL resultante y la salida resultante correspondientes a patrones de agregación comunes.
Agregar todas las filas de una tabla
Use este patrón cuando desee una fila de resumen para toda la entidad.
Tabla 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 | año | Páginas |
|---|---|---|---|
| 1 | Conceptos básicos de GraphQL | 2023 | 120 |
| 2 | API avanzadas | 2023 | 450 |
| 3 | Patrones de datos | 2023 | 390 |
| 4 | API en la nube | 2024 | 140 |
| 5 | Componentes internos del entorno de ejecución | 2024 | 510 |
| 6 | Optimización de consultas | 2024 | 250 |
Consulta de GraphQL
{
books {
groupBy {
aggregations {
totalPages: sum(field: pages)
averagePages: avg(field: pages)
shortestBook: min(field: pages)
longestBook: max(field: pages)
bookCount: count(field: id)
}
}
}
}
SQL resultante
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;
Salida resultante
{
"data": {
"books": {
"groupBy": [
{
"aggregations": {
"totalPages": 1860,
"averagePages": 310,
"shortestBook": 120,
"longestBook": 510,
"bookCount": 6
}
}
]
}
}
}
| totalPages | averagePages | shortestBook | longestBook | bookCount |
|---|---|---|---|---|
| 1860 | 310 | 120 | 510 | 6 |
Agrupar filas por un campo
Utilice groupBy(fields: [...]) para devolver una fila agregada por cada valor de campo. Los nombres de campo son valores de enumeración graphQL, no cadenas.
Tabla 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 | año | Páginas |
|---|---|---|---|
| 1 | Conceptos básicos de GraphQL | 2023 | 120 |
| 2 | API avanzadas | 2023 | 450 |
| 3 | Patrones de datos | 2023 | 390 |
| 4 | API en la nube | 2024 | 140 |
| 5 | Aspectos internos del entorno de ejecución | 2024 | 510 |
| 6 | Optimización de consultas | 2024 | 250 |
Consulta de GraphQL
{
books(orderBy: { year: ASC }) {
groupBy(fields: [year]) {
fields { year }
aggregations {
totalPages: sum(field: pages)
averagePages: avg(field: pages)
}
}
}
}
SQL resultante
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;
Salida resultante
{
"data": {
"books": {
"groupBy": [
{
"fields": {
"year": 2023
},
"aggregations": {
"totalPages": 960,
"averagePages": 320
}
},
{
"fields": {
"year": 2024
},
"aggregations": {
"totalPages": 900,
"averagePages": 300
}
}
]
}
}
}
| año | totalPages | promedio de páginas |
|---|---|---|
| 2023 | 960 | 320 |
| 2024 | 900 | 300 |
Agrupar filas en una vista
La agregación también funciona para entidades basadas en vistas. Configure un campo de clave para la vista para que data API Builder pueda exponerlo como una entidad.
vista 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 | departamento | edad |
|---|---|---|
| 1 | Ingeniería | 29 |
| 2 | Ingeniería | 41 |
| 3 | Ventas | 34 |
| 4 | Ventas | 52 |
| 5 | Apoyo | 25 |
| 6 | Apoyo | 38 |
| 7 | Ingeniería | 45 |
Configure la vista con id como campo de clave:
dab add EmployeeAgeReport --source dbo.EmployeeAgeReport --source.type view --source.key-fields id --permissions "anonymous:read"
Consulta de GraphQL
{
employeeAgeReports(orderBy: { department: ASC }) {
groupBy(fields: [department]) {
fields { department }
aggregations {
youngest: min(field: age)
oldest: max(field: age)
employeeCount: count(field: id)
}
}
}
}
SQL resultante
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;
Salida resultante
{
"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
}
}
]
}
}
}
| departamento | más joven | más antiguo | numeroDeEmpleados |
|---|---|---|---|
| Ingeniería | 29 | 45 | 3 |
| Ventas | 34 | 52 | 2 |
| Apoyo | 25 | 38 | 2 |
Filtrar filas antes de la agregación
Use filter en la consulta de colección para limitar las filas de origen antes de que Data API Builder las agrupe y agregue.
vista 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 | departamento | edad |
|---|---|---|
| 1 | Ingeniería | 29 |
| 2 | Ingeniería | 41 |
| 3 | Ventas | 34 |
| 4 | Ventas | 52 |
| 5 | Apoyo | 25 |
| 6 | Apoyo | 38 |
| 7 | Ingeniería | 45 |
Consulta de 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)
}
}
}
}
SQL resultante
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;
Para esta consulta, @param1 es 30.
Salida resultante
{
"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
}
}
]
}
}
}
| departamento | más joven | más antiguo | Número de empleados |
|---|---|---|---|
| Ingeniería | 41 | 45 | 2 |
| Ventas | 34 | 52 | 2 |
| Apoyo | 38 | 38 | 1 |
Filtrado de grupos mediante having
Use having en una función de agregado para filtrar grupos después de la agregación. Este patrón se asigna a una cláusula SQL HAVING .
Tabla 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 | category | precio |
|---|---|---|
| 1 | Electrónica | 5000,00 |
| 2 | Electrónica | 10000,00 |
| 3 | Mobiliario | 4000.00 |
| 4 | Mobiliario | 8000.00 |
| 5 | Libros | 100.00 |
| 6 | Libros | 200.00 |
Consulta de GraphQL
{
products(orderBy: { category: ASC }) {
groupBy(fields: [category]) {
fields { category }
aggregations {
totalValue: sum(field: price, having: { gt: 10000 })
averagePrice: avg(field: price)
}
}
}
}
SQL resultante
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;
Para esta consulta, @param1 es 10000.
Salida resultante
{
"data": {
"products": {
"groupBy": [
{
"fields": {
"category": "Electronics"
},
"aggregations": {
"totalValue": 15000,
"averagePrice": 7500
}
},
{
"fields": {
"category": "Furniture"
},
"aggregations": {
"totalValue": 12000,
"averagePrice": 6000
}
}
]
}
}
}
| category | valor total | precio medio |
|---|---|---|
| Electrónica | 15000 | 7500 |
| Mobiliario | 12000 | 6000 |
Recuento de valores distintos
Use distinct: true con count para contar valores únicos en cada grupo.
Tabla 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 |
Consulta de 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)
}
}
}
}
SQL resultante
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;
Salida resultante
{
"data": {
"orders": {
"groupBy": [
{
"fields": {
"customer_id": 101
},
"aggregations": {
"uniqueProducts": 5,
"totalOrders": 6
}
},
{
"fields": {
"customer_id": 102
},
"aggregations": {
"uniqueProducts": 3,
"totalOrders": 4
}
}
]
}
}
}
| customer_id | uniqueProducts | Total de pedidos |
|---|---|---|
| 101 | 5 | 6 |
| 102 | 3 | 4 |
Errores comunes
- Seleccione
groupBydentro del campo de colección. No pasesgroupBycomo argumento de tipo colección. - Use
aggregations, noaggregates. - Use
avg, noaverage. - Use valores de enumeración de campo, como
fields: [year]. No ponga entre comillas los nombres de campo. - No seleccione
itemsygroupByen la misma consulta de recopilación. - Al agrupar por campos, seleccione solo los mismos campos dentro del
fieldsobjeto .