Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Le générateur d’API de données (DAB) prend en charge l’agrégation et le regroupement GraphQL pour les bases de données de famille SQL et Azure Synapse Analytics (pool SQL dédié). Les agrégations vous permettent de résumer les champs numériques et les résultats de groupe sans écrire de code API personnalisé. L’agrégation et groupBy ne sont pas disponibles pour Azure Cosmos DB pour NoSQL, PostgreSQL ou MySQL.
Prerequisites
- Base de données prise en charge :
- SQL Server 2016 ou ultérieur
- Azure SQL Database
- Azure SQL Managed Instance (Instance gérée Azure SQL)
- Microsoft Fabric SQL
- Azure Synapse Analytics (pool SQL dédié uniquement)
- CLI du générateur d'API de données. Installer l’interface CLI
- Fichier de configuration DAB avec votre entité exposée via GraphQL.
- Un client GraphQL (par exemple, Banana Cake Pop ou GraphQL Playground) pour exécuter des requêtes.
Bases de données prises en charge
| Base de données | Prise en charge de l’agrégation |
|---|---|
| SQL Server / Azure SQL / Microsoft Fabric SQL | ✅ Oui |
| Azure Synapse (pool SQL dédié) | ✅ Oui |
| Azure Synapse (SQL pool serverless) | ❌ Non |
| PostgreSQL | ❌ Non |
| MySQL | ❌ Non |
| Azure Cosmos DB pour NoSQL | ❌ Non |
Fonctions d'agrégation
DAB prend en charge les fonctions d’agrégation suivantes :
| Fonction | S’applique à | Descriptif |
|---|---|---|
sum |
Champs numériques uniquement | Total de toutes les valeurs |
average |
Champs numériques uniquement | Moyenne de toutes les valeurs |
min |
Champs numériques uniquement | Valeur minimale |
max |
Champs numériques uniquement | Valeur maximale |
count |
N’importe quel champ | Nombre de valeurs non nulles |
Constraints
-
sum,average,minetmaxfonctionne uniquement sur les types de données numériques (int, decimal, float, etc.). -
countfonctionne sur n’importe quel type de données, y compris les chaînes et les dates. - Si une table n’a pas de colonnes numériques, DAB ne génère pas de nœuds d’agrégation pour cette entité. Vous pouvez toujours utiliser
countsur des champs non numériques.
Modificateurs facultatifs
| Modificateur | Objectif | Example |
|---|---|---|
distinct: true |
Compter les valeurs uniques uniquement | Compter des clients distincts |
having: { ... } |
Filtrer les groupes après l’agrégation | Afficher les groupes avec la somme > 1000 |
Exécuter le runtime DAB
Démarrez DAB avec votre fichier de configuration afin que le point de terminaison GraphQL soit disponible.
dab start
Résultats agrégés des requêtes
Cette section décrit un exemple complet montrant le schéma de table, la requête GraphQL, la réponse SQL générée et JSON.
Schéma de table
CREATE TABLE books (
id INT PRIMARY KEY,
title NVARCHAR(200),
year INT,
pages INT
);
Requête GraphQL
Utilisez GraphQL pour regrouper des lignes et retourner des valeurs d’agrégation pour les champs numériques.
{
books(
groupBy: { fields: ["year"] }
) {
items {
year
}
aggregates {
pages {
sum
average
min
max
}
}
}
}
-
groupBy.fieldsregroupe les lignes par les colonnes spécifiées. -
aggregatesexpose les fonctions d’agrégation pour les champs numériques (par exemple,pages). - Le schéma GraphQL expose uniquement les agrégats pour les champs qui les prennent en charge ; utilisez l’introspection de schéma dans votre client pour confirmer les champs et fonctions d’agrégation disponibles.
SQL généré
DAB traduit la requête GraphQL en 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
Réponse 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 }
]
}
}
}
}
Les tableaux items et aggregates s’alignent par index : le premier élément de aggregates.pages correspond au premier groupe de items.
Agréger sans regroupement
Calculez les agrégats sur toutes les lignes lorsque vous omettez groupBy.
Requête GraphQL
{
books {
aggregates {
pages {
sum
average
min
max
count
}
id {
count
}
}
}
}
SQL généré
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
Réponse JSON
{
"data": {
"books": {
"aggregates": {
"pages": {
"sum": 15420,
"average": 308,
"min": 120,
"max": 850,
"count": 50
},
"id": {
"count": 50
}
}
}
}
}
Sans groupBy, la réponse retourne un objet unique (et non un tableau), car toutes les lignes s’réduisent en un résultat.
Regrouper par un ou plusieurs champs
Regroupez les lignes par une ou plusieurs colonnes et renvoyez des agrégats par groupe.
Schéma de table
CREATE TABLE sales (
id INT PRIMARY KEY,
year INT,
category NVARCHAR(50),
revenue DECIMAL(10,2),
quantity INT
);
Requête GraphQL
{
sales(
groupBy: { fields: ["year", "category"] }
) {
items {
year
category
}
aggregates {
revenue {
sum
average
}
quantity {
sum
}
}
}
}
SQL généré
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
Réponse 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 réponse retourne des tableaux pour items et des agrégats dans le même ordre afin de pouvoir aligner les groupes avec leurs valeurs agrégées.
HAVING pour filtrer les résultats agrégés
Permet having de filtrer des groupes après l’agrégation. Cela équivaut à la clause de HAVING SQL.
Schéma de table
CREATE TABLE products (
id INT PRIMARY KEY,
category NVARCHAR(50),
price DECIMAL(10,2)
);
Requête GraphQL
{
products(
groupBy: { fields: ["category"] }
) {
items { category }
aggregates {
price {
sum(having: { gt: 10000 })
average
}
}
}
}
SQL généré
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
Réponse JSON
Seules les catégories où la somme dépasse 1 0000 sont retournées :
{
"data": {
"products": {
"items": [
{ "category": "Electronics" },
{ "category": "Furniture" }
],
"aggregates": {
"price": [
{ "sum": 15000.00, "average": 300.00 },
{ "sum": 12000.00, "average": 400.00 }
]
}
}
}
}
OPÉRATEURS HAVING
| Operator | Équivalent 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 } |
Note
Chaque having filtre s’applique indépendamment à sa fonction d’agrégation. Vous ne pouvez pas créer de conditions d’agrégation croisée comme « sum > 1000 OR count < 10 » dans une seule requête GraphQL.
DISTINCT dans les agrégations
Compter les valeurs uniques avec distinct: true.
Schéma de table
CREATE TABLE orders (
id INT PRIMARY KEY,
customer_id INT,
product_id INT
);
Requête GraphQL
{
orders(
groupBy: { fields: ["customer_id"] }
) {
items { customer_id }
aggregates {
product_id {
count(distinct: true)
count
}
}
}
}
SQL généré
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
Réponse JSON
{
"data": {
"orders": {
"items": [
{ "customer_id": 101 },
{ "customer_id": 102 }
],
"aggregates": {
"product_id": [
{ "count": 5 },
{ "count": 3 }
]
}
}
}
}
Le premier count (avec distinct: true) retourne des produits uniques par client. La deuxième count retourne le total des commandes.
Note
Lors de la demande de plusieurs agrégats sur le même champ, DAB les retourne dans l’ordre demandé. Utilisez des alias (par exemple uniqueProducts: count(distinct: true)) pour documenter automatiquement les réponses.
Combiner des filtres avec l’agrégation
Appliquez filter aux lignes avant le regroupement et having aux groupes après l’agrégation. Comprendre l’ordre des opérations est essentiel :
-
Filter (SQL
WHERE) supprime les lignes avant le regroupement - Group by regroupe les lignes restantes dans des groupes
- L’agrégation calcule la somme/moyenne/minimum/maximum/nombre par groupe
- Having supprime les groupes qui ne correspondent pas à la condition.
Requête GraphQL
{
sales(
filter: { year: { gte: 2023 } }
groupBy: { fields: ["region"] }
) {
items { region }
aggregates {
revenue { sum average }
}
}
}
SQL généré
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
Conseil / Astuce
Permet filter d’exclure des lignes avant l’agrégation. Permet having de filtrer des groupes après l’agrégation.
Utiliser des alias avec des agrégations
Créez des noms de champs explicites à l’aide d’alias GraphQL.
{
products(
groupBy: { fields: ["category"] }
) {
items { category }
aggregates {
price {
totalRevenue: sum
avgPrice: average
cheapest: min
mostExpensive: max
productCount: count
}
}
}
}
Introspection de schéma
Utilisez l’introspection pour voir quels agrégats sont disponibles pour une entité.
{
__type(name: "BooksAggregates") {
fields {
name
type { name }
}
}
}
Les champs numériques exposent sum, , averagemin, maxet count. Les champs non numériques exposent count.
Conseils et limitations
- L'agrégation et
groupBys'appliquent uniquement à SQL Server, Azure SQL, Microsoft Fabric SQL, et au pool SQL dédié Azure Synapse. - Les agrégats s’exécutent sur des champs numériques ;
countfonctionne sur n’importe quel champ. Les tables sans colonnes numériques n’exposent quecount. - Le regroupement s’applique aux champs sur la même entité (aucun groupe d’entités inter-entitésBy).
- Les agrégations volumineuses peuvent être coûteuses ; indexez vos colonnes groupBy et filtrez les lignes avant de les regrouper lorsque cela est possible.
- Créez des index sur des colonnes fréquemment utilisées
groupBypour améliorer les performances des requêtes.
Résolution des problèmes
Erreur : Le champ ne prend pas en charge l’agrégation
Cause : Utilisation sum, , averageminou max sur un champ non numérique.
Solution:
- Utilisez l’introspection de schéma pour vérifier les types de champs.
- Utiliser
countpour les champs non numériques. - Vérifiez les mappages de champs si vous utilisez des noms de champs personnalisés.
Erreur : Nœuds d’agrégation introuvables
Cause : l’entité n’a pas de colonnes numériques.
Solution:
- Vérifiez que le schéma de table comporte au moins une colonne numérique.
- Utilisez
countpour agréger des champs non numériques si nécessaire.
Requêtes d’agrégation lentes
Cause : tables volumineuses sans index appropriés.
Solution:
- Créez des index sur les colonnes
groupBy. - Permet
filterde limiter les lignes avant l’agrégation. - Utilisez
havingpour réduire le nombre de groupes retournés.