GraphQL ile veri toplama

Veri API oluşturucusu, SQL Server ailesi ve Azure Synapse Analytics Ayrılmış SQL havuzu varlıkları için GraphQL toplamayı destekler. sum, avg, min, max ve count değerlerini hesaplamak için koleksiyon sorgusunda groupBy alanını kullanın.

Bu makaledeki örneklerde okuma iznine sahip SQL Server ve GraphQL varlıkları kullanılır. Veri API oluşturucusu, her senaryoda gösterilen deyimler gibi SQL oluşturur. Parametre değerleri çalışma zamanında sorgu parametreleri olarak görünür. sum, avg, minve max işlevleri sayısal alanlara uygulanır. İşlev count herhangi bir alanda çalışır.

Important

Azure Cosmos DB for NoSQL, PostgreSQL veya MySQL için toplama kullanılamaz.

Toplama varsayılan olarak etkindir. Kapatmak için, yapılandırma dosyanızda runtime.graphql altında enable-aggregation değerini false olarak ayarlayın. Agregasyon sorguları, varsayılan olarak 100 grup içeren bir sayfa döndürür. first Koleksiyon sorgusundaki bağımsız değişkenini kullanarak en yüksek değeri değiştirin, örneğinbooks(first: 500). ile runtime.pagination.default-page-sizevarsayılanı ayarlayın.

GraphQL şema eklemeleri

Toplamayı etkinleştirdiğinizde, Veri API oluşturucusu desteklenen her GraphQL koleksiyonuna toplama alanları ve oluşturulan türler ekler. Tam olarak oluşturulan tür adları varlığa özgüdür ve GraphQL introspection aracılığıyla görülebilir, ancak sorgu söz dizimi varlıklar arasında tutarlıdır.

Aşağıdaki kod parçacıkları, tam GraphQL sorgularını değil söz dizimi biçimlerini gösterir.

groupBy

Koleksiyon için gruplandırılmış satırları döndürür. Bir toplama sorgusunda, items yerine bu üyeyi seçin.

<collection> { groupBy { ... } }

groupBy(fields: [...])

Gruplanacak varlık alanlarını listeler. Tüm satırları tek bir grupta toplamak için fields öğesini atlayın.

<collection> { groupBy(fields: [<field>, ...]) { ... } }

fields

Toplama sonucundaki her satır için gruplandırılmış alan değerlerini döndürür.

groupBy(fields: [<field>]) { fields { <field> } }

aggregations

Her grup için toplam işlev seçimlerini içerir.

groupBy { aggregations { <alias>: <function>(field: <field>) } }

sum, avg, min ve max

Sayısal alanları toplama.

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

Bir alanın değerlerini sayar.

aggregations { <alias>: count(field: <field>) }

field

Toplama yapılacak varlık alanını tanımlar. Alan adları, dizeler değil, enum değerleridir.

<function>(field: <field>)

having

Veri API'sinin oluşturucusu toplama değerini hesapladıktan sonra grupları filtreler.

aggregations { <alias>: <function>(field: <field>, having: { <operator>: <value> }) }

distinct

ile countkullanıldığında benzersiz değerleri sayar.

aggregations { <alias>: count(field: <field>, distinct: true) }

Veri API Oluşturucusu, grup satırı türleri, gruplandırılmış alan türleri, toplama seçim türleri, alan numaralandırmaları ve having giriş türleri dahil olmak üzere, bu üyeler için varlığa özel GraphQL türleri oluşturur. Sorguda oluşturulan türleri adlandırmanız gerekmez.

Samples

Aşağıdaki örneklerde SQL tablosu, GraphQL sorgusu, sonuçta SQL ve yaygın toplama desenleri için sonuç çıktısı gösterilmektedir.

Tablodaki tüm satırları toplama

Varlığın tamamı için bir özet satırı istediğinizde bu düzeni kullanın.

SQL tablosu

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 yıl pages
1 GraphQL Temel Bilgileri 2023 120
2 Gelişmiş API'ler 2023 450
3 Veri Desenleri 2023 390
4 Bulut API'leri 2024 140
5 Çalışma Zamanı İç Yapısı 2024 510
6 Sorgu Optimizasyonu 2024 250

GraphQL sorgusu

{
  books {
    groupBy {
      aggregations {
        totalPages: sum(field: pages)
        averagePages: avg(field: pages)
        shortestBook: min(field: pages)
        longestBook: max(field: pages)
        bookCount: count(field: id)
      }
    }
  }
}

Sonuçta elde edilen SQL

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;

Sonuç çıktı

{
  "data": {
    "books": {
      "groupBy": [
        {
          "aggregations": {
            "totalPages": 1860,
            "averagePages": 310,
            "shortestBook": 120,
            "longestBook": 510,
            "bookCount": 6
          }
        }
      ]
    }
  }
}
totalPages averagePages shortestBook longestBook bookCount
1860 310 120 510 6

Satırları bir alana göre gruplandırma

Alan değeri başına bir toplama satırı döndürmek için kullanın groupBy(fields: [...]) . Alan adları, dizeler değil, GraphQL enum değerleridir.

SQL tablosu

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 yıl pages
1 GraphQL Temel Bilgileri 2023 120
2 Gelişmiş API'ler 2023 450
3 Veri Desenleri 2023 390
4 Bulut API'leri 2024 140
5 Çalışma Zamanının İç Yapısı 2024 510
6 Sorgu Ayarı 2024 250

GraphQL sorgusu

{
  books(orderBy: { year: ASC }) {
    groupBy(fields: [year]) {
      fields { year }
      aggregations {
        totalPages: sum(field: pages)
        averagePages: avg(field: pages)
      }
    }
  }
}

Sonuçta elde edilen SQL

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;

Sonuç çıktı

{
  "data": {
    "books": {
      "groupBy": [
        {
          "fields": {
            "year": 2023
          },
          "aggregations": {
            "totalPages": 960,
            "averagePages": 320
          }
        },
        {
          "fields": {
            "year": 2024
          },
          "aggregations": {
            "totalPages": 900,
            "averagePages": 300
          }
        }
      ]
    }
  }
}
yıl totalPages Ortalama Sayfa Sayısı
2023 960 320
2024 900 300

Görünümden satırları gruplandırma

Toplulaştırma, görünüme dayalı varlıklar için de çalışır. Veri API'sinin oluşturucusunun bunu varlık olarak kullanıma sunması için görünüm için bir anahtar alanı yapılandırın.

SQL görünümü

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 bölüm / departman yaş
1 Mühendislik 29
2 Mühendislik 41
3 Sales 34
4 Sales 52
5 Support 25
6 Support 38
7 Mühendislik 45

Görünümü, anahtar alan olarak id ile yapılandırın:

dab add EmployeeAgeReport --source dbo.EmployeeAgeReport --source.type view --source.key-fields id --permissions "anonymous:read"

GraphQL sorgusu

{
  employeeAgeReports(orderBy: { department: ASC }) {
    groupBy(fields: [department]) {
      fields { department }
      aggregations {
        youngest: min(field: age)
        oldest: max(field: age)
        employeeCount: count(field: id)
      }
    }
  }
}

Sonuçta elde edilen SQL

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;

Sonuç çıktı

{
  "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
          }
        }
      ]
    }
  }
}
bölüm / departman En genç en eski Çalışan Sayısı
Mühendislik 29 45 3
Sales 34 52 2
Support 25 38 2

Toplamadan önce satırları filtreleme

Data API Builder bunları gruplandırıp toplulaştırmadan önce kaynak satırlarını sınırlamak için koleksiyon sorgusunda filter kullanın.

SQL görünümü

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 bölüm / departman yaş
1 Mühendislik 29
2 Mühendislik 41
3 Sales 34
4 Sales 52
5 Support 25
6 Support 38
7 Mühendislik 45

GraphQL sorgusu

{
  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)
      }
    }
  }
}

Sonuçta elde edilen SQL

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;

Bu sorgu için, @param1 şeklindedir 30.

Sonuç çıktı

{
  "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
          }
        }
      ]
    }
  }
}
bölüm / departman en genç En eski Çalışan Sayısı
Mühendislik 41 45 2
Sales 34 52 2
Support 38 38 1

having kullanarak grupları filtreleyin

Toplamadan sonra grupları filtrelemek için toplama işlevinde kullanın having . Bu desen, bir SQL HAVING yan tümcesine karşılık gelir.

SQL tablosu

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 fiyat
1 Elektronik 5000.00
2 Elektronik 10000.00
3 Mobilya 4000.00
4 Mobilya 8000.00
5 Kitaplar 100,00
6 Kitaplar 200,00

GraphQL sorgusu

{
  products(orderBy: { category: ASC }) {
    groupBy(fields: [category]) {
      fields { category }
      aggregations {
        totalValue: sum(field: price, having: { gt: 10000 })
        averagePrice: avg(field: price)
      }
    }
  }
}

Sonuçta elde edilen SQL

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;

Bu sorgu için, @param1 şeklindedir 10000.

Sonuç çıktı

{
  "data": {
    "products": {
      "groupBy": [
        {
          "fields": {
            "category": "Electronics"
          },
          "aggregations": {
            "totalValue": 15000,
            "averagePrice": 7500
          }
        },
        {
          "fields": {
            "category": "Furniture"
          },
          "aggregations": {
            "totalValue": 12000,
            "averagePrice": 6000
          }
        }
      ]
    }
  }
}
category Toplam Değer Ortalama Fiyat
Elektronik 15000 7.500
Mobilya 12000 6000

Ayrı değerleri sayma

Her gruptaki benzersiz değerleri saymak için distinct: true ile count kullanın.

SQL tablosu

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

GraphQL sorgusu

{
  orders(orderBy: { customer_id: ASC }) {
    groupBy(fields: [customer_id]) {
      fields { customer_id }
      aggregations {
        uniqueProducts: count(field: product_id, distinct: true)
        totalOrders: count(field: id)
      }
    }
  }
}

Sonuçta elde edilen SQL

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;

Sonuç çıktı

{
  "data": {
    "orders": {
      "groupBy": [
        {
          "fields": {
            "customer_id": 101
          },
          "aggregations": {
            "uniqueProducts": 5,
            "totalOrders": 6
          }
        },
        {
          "fields": {
            "customer_id": 102
          },
          "aggregations": {
            "uniqueProducts": 3,
            "totalOrders": 4
          }
        }
      ]
    }
  }
}
customer_id uniqueProducts Toplam Siparişler
101 5 6
102 3 4

Yaygın hatalar

  • Koleksiyon alanı içindeki groupBy öğesini seçin. groupBy öğesini bir koleksiyon bağımsız değişkeni olarak geçirmeyin.
  • aggregations'yi, aggregates'ye tercih edin.
  • avg'yi, average'ye tercih edin.
  • fields: [year] gibi alan enum değerlerini kullanın. Alan adlarını alıntı yapmayın.
  • Aynı koleksiyon sorgusunda items ve groupBy seçmeyin.
  • Alanlara göre gruplandırdığınızda, nesnenin içinde fields yalnızca aynı alanları seçin.