Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Penyusun API Data (DAB) mendukung agregasi dan pengelompokan GraphQL untuk database keluarga SQL dan Azure Synapse Analytics (kumpulan SQL Khusus). Agregasi memungkinkan Anda meringkas bidang numerik dan hasil grup tanpa menulis kode API kustom. Agregasi dan groupBy tidak tersedia untuk Azure Cosmos DB untuk NoSQL, PostgreSQL, atau MySQL.
Prasyarat
- Database yang didukung:
- SQL Server 2016 atau yang lebih baru
- Azure SQL Database
- Azure SQL Managed Instance
- Microsoft Fabric SQL
- Azure Synapse Analytics (kumpulan SQL Terdedikasi)
- CLI pembangun API Data. Menginstal CLI
- File konfigurasi DAB dengan entitas Anda ditampilkan menggunakan GraphQL.
- Klien GraphQL (misalnya, Banana Cake Pop atau GraphQL Playground) untuk menjalankan kueri.
Database yang didukung
| Database | Dukungan agregasi |
|---|---|
| SQL Server / Azure SQL / Microsoft Fabric SQL | ✅ Ya |
| Azure Synapse (Kumpulan SQL Khusus) | ✅ Ya |
| Azure Synapse (Kumpulan SQL Tanpa Server) | ❌ Tidak |
| PostgreSQL | ❌ Tidak |
| MySQL | ❌ Tidak |
| Azure Cosmos DB for NoSQL | ❌ Tidak |
Fungsi agregat
DAB mendukung fungsi agregat berikut:
| Function | Berlaku pada | Description |
|---|---|---|
sum |
Bidang numerik saja | Jumlah total nilai |
average |
Bidang numerik saja | Rata-rata semua nilai |
min |
Bidang numerik saja | Nilai minimum |
max |
Bidang numerik saja | Nilai maksimal |
count |
Bidang apa pun | Jumlah nilai non-null |
Constraints
-
sum, ,average,mindanmaxhanya bekerja pada jenis data numerik (int, desimal, float, dll.). -
countbekerja pada jenis data apa pun, termasuk string dan tanggal. - Jika tabel tidak memiliki kolom numerik, DAB tidak menghasilkan simpul agregasi untuk entitas tersebut. Anda masih dapat menggunakan
countpada bidang non-numerik.
Pengubah opsional
| Pengubah | Tujuan | Example |
|---|---|---|
distinct: true |
Hitung nilai unik saja | Menghitung pelanggan yang berbeda |
having: { ... } |
Memilah grup setelah agregasi | Perlihatkan grup dengan jumlah > 1000 |
Menjalankan runtime DAB
Mulai DAB dengan file konfigurasi Anda agar endpoint GraphQL dapat diakses.
dab start
Hasil agregat kueri
Bagian ini menjelaskan contoh lengkap yang memperlihatkan skema tabel, kueri GraphQL, respons SQL yang dihasilkan, dan JSON.
Skema tabel
CREATE TABLE books (
id INT PRIMARY KEY,
title NVARCHAR(200),
year INT,
pages INT
);
Kueri GraphQL
Gunakan GraphQL untuk mengelompokkan baris dan mengembalikan nilai agregat untuk bidang numerik.
{
books(
groupBy: { fields: ["year"] }
) {
items {
year
}
aggregates {
pages {
sum
average
min
max
}
}
}
}
-
groupBy.fieldsmengelompokkan baris menurut kolom yang ditentukan. -
aggregatesmengekspos fungsi agregat untuk bidang numerik (misalnya,pages). - Skema GraphQL hanya mengekspos agregat untuk bidang yang mendukungnya; gunakan introspeksi skema di klien Anda untuk mengonfirmasi bidang dan fungsi agregat yang tersedia.
SQL yang dihasilkan
DAB menerjemahkan kueri GraphQL ke dalam 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
Tanggapan 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 }
]
}
}
}
}
Array items dan aggregates disejajarkan menurut indeks—elemen pertama di aggregates.pages sesuai dengan grup pertama di items.
Agregat tanpa pengelompokan
Hitung agregat di semua baris saat Anda menghilangkan groupBy.
Kueri GraphQL
{
books {
aggregates {
pages {
sum
average
min
max
count
}
id {
count
}
}
}
}
SQL yang dihasilkan
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
Tanggapan JSON
{
"data": {
"books": {
"aggregates": {
"pages": {
"sum": 15420,
"average": 308,
"min": 120,
"max": 850,
"count": 50
},
"id": {
"count": 50
}
}
}
}
}
Tanpa groupBy, respons mengembalikan satu objek (bukan array) karena semua baris diciutkan menjadi satu hasil.
Mengelompokkan menurut satu atau beberapa bidang
Kelompokkan baris menurut satu atau beberapa kolom dan kembalikan agregat per grup.
Skema tabel
CREATE TABLE sales (
id INT PRIMARY KEY,
year INT,
category NVARCHAR(50),
revenue DECIMAL(10,2),
quantity INT
);
Kueri GraphQL
{
sales(
groupBy: { fields: ["year", "category"] }
) {
items {
year
category
}
aggregates {
revenue {
sum
average
}
quantity {
sum
}
}
}
}
SQL yang dihasilkan
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
Tanggapan 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 }
]
}
}
}
}
Respons mengembalikan array untuk items dan mengagregasi dalam urutan yang sama sehingga Anda dapat meratakan grup dengan nilai agregatnya.
Penggunaan "HAVING" untuk memfilter hasil agregat
Gunakan having untuk memfilter grup setelah agregasi. Ini setara dengan klausul SQL HAVING .
Skema tabel
CREATE TABLE products (
id INT PRIMARY KEY,
category NVARCHAR(50),
price DECIMAL(10,2)
);
Kueri GraphQL
{
products(
groupBy: { fields: ["category"] }
) {
items { category }
aggregates {
price {
sum(having: { gt: 10000 })
average
}
}
}
}
SQL yang dihasilkan
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
Tanggapan JSON
Hanya kategori di mana jumlah melebihi 10000 dikembalikan:
{
"data": {
"products": {
"items": [
{ "category": "Electronics" },
{ "category": "Furniture" }
],
"aggregates": {
"price": [
{ "sum": 15000.00, "average": 300.00 },
{ "sum": 12000.00, "average": 400.00 }
]
}
}
}
}
Operator HAVING
| Operator | Setara dengan 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 } |
Nota
Setiap having filter berlaku secara independen pada fungsi agregatnya. Anda tidak dapat membuat kondisi agregat silang seperti "jumlah > 1000 ATAU hitungan < 10" dalam satu kueri GraphQL.
BERBEDA dalam agregasi
Hitung nilai unik dengan distinct: true.
Skema tabel
CREATE TABLE orders (
id INT PRIMARY KEY,
customer_id INT,
product_id INT
);
Kueri GraphQL
{
orders(
groupBy: { fields: ["customer_id"] }
) {
items { customer_id }
aggregates {
product_id {
count(distinct: true)
count
}
}
}
}
SQL yang dihasilkan
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
Tanggapan JSON
{
"data": {
"orders": {
"items": [
{ "customer_id": 101 },
{ "customer_id": 102 }
],
"aggregates": {
"product_id": [
{ "count": 5 },
{ "count": 3 }
]
}
}
}
}
Yang pertama count (dengan distinct: true) menghasilkan produk unik per pelanggan. Yang kedua count mengembalikan total pesanan.
Nota
Saat meminta beberapa agregat pada bidang yang sama, DAB mengembalikannya dalam urutan yang diminta. Gunakan alias (misalnya, uniqueProducts: count(distinct: true)) untuk membuat respons dokumentasi mandiri.
Padu padankan filter dengan agregasi
Terapkan filter ke baris sebelum pengelompokan, dan having ke grup setelah agregasi. Memahami urutan operasi sangat penting:
-
Filter (SQL
WHERE) menghapus baris sebelum pengelompokan - Group by mengumpulkan baris yang tersisa menjadi kelompok-kelompok
- Agregat menghitung total/rata-rata/min/maks/jumlah data per grup
- Pada HAVING grup yang tidak cocok dengan kondisi dihapus
Kueri GraphQL
{
sales(
filter: { year: { gte: 2023 } }
groupBy: { fields: ["region"] }
) {
items { region }
aggregates {
revenue { sum average }
}
}
}
SQL yang dihasilkan
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
Petunjuk / Saran
Gunakan filter untuk mengecualikan baris sebelum agregasi. Gunakan having untuk memfilter grup setelah agregasi.
Menggunakan alias dengan agregasi
Buat nama bidang yang bermakna menggunakan alias GraphQL.
{
products(
groupBy: { fields: ["category"] }
) {
items { category }
aggregates {
price {
totalRevenue: sum
avgPrice: average
cheapest: min
mostExpensive: max
productCount: count
}
}
}
}
Introspeksi skema
Gunakan introspeksi untuk melihat agregat mana yang tersedia untuk entitas.
{
__type(name: "BooksAggregates") {
fields {
name
type { name }
}
}
}
Bidang numerik mengekspos sum, , average, minmax, dan count. Bidang non-numerik mengekspos count.
Tips dan batasan
- Agregasi dan
groupByberlaku untuk kumpulan SQL Server, Azure SQL, Microsoft Fabric SQL, dan Azure Synapse Dedicated SQL saja. - Agregat berjalan pada bidang numerik;
countbekerja di bidang apa pun. Tabel tanpa kolom numerik hanya mengeksposcount. - Pengelompokan berlaku untuk bidang pada entitas yang sama (tidak ada groupBy lintas entitas).
- Agregasi yang besar bisa mahal; lakukan pengindeksan pada kolom-kolom yang digunakan dalam perintah groupBy dan lakukan penyaringan baris sebelum mengelompokkan jika memungkinkan.
- Buat indeks pada kolom yang sering digunakan
groupByuntuk meningkatkan performa kueri.
Troubleshooting
Kesalahan: Bidang tidak mendukung agregasi
Penyebab: Menggunakan sum, average, min, atau max pada bidang non-numerik.
Solusi:
- Gunakan introspeksi skema untuk memverifikasi jenis bidang.
- Gunakan
countuntuk bidang non-numerik. - Periksa pemetaan bidang jika menggunakan nama bidang kustom.
Kesalahan: Simpul agregasi tidak ditemukan
Penyebab: Entitas tidak memiliki kolom numerik.
Solusi:
- Verifikasi skema tabel memiliki setidaknya satu kolom numerik.
- Gunakan
countagregat pada bidang non-numerik jika diperlukan.
Kueri agregasi lambat
Penyebab: Tabel besar tanpa indeks yang tepat.
Solusi:
- Membuat indeks pada
groupBykolom. - Gunakan
filteruntuk membatasi baris sebelum agregasi. - Gunakan
havinguntuk mengurangi jumlah grup yang dikembalikan.