İçeriğe geç

Gruplama ve Toplamalar

Archie Core, GraphQL API’si aracılığıyla güçlü gruplama ve toplama yetenekleri sunar. Kayıtları alan değerlerine göre gruplayabilir, toplama işlevleri hesaplayabilir (COUNT, SUM, AVG, MIN, MAX, COUNT_DISTINCT), HAVING koşullarıyla grupları filtreleyebilir ve sonuçları toplam değerlere göre sıralayabilirsiniz.

Gruplama ve toplamalar kullanırken, herhangi bir liste sorgusunda aşağıdaki argümanlar mevcuttur:

ArgümanTipAçıklama
groupBy[{TableName}GroupBy]Sonuçları gruplandırmak için alanlar
aggregateBy[{TableName}AggregateInput]Hesaplanacak toplama işlevleri
having[{TableName}HavingFilterInput]Grupları toplam sonuçlara göre filtreleme
aggregateSort[{TableName}AggregateSortInput]Sonuçları toplam değerlere göre sıralama

Bu argümanlar filter, first, skip ve orderBy gibi standart argümanlarla birleştirilebilir.

groupBy argümanı, gruplandırılacak alanları temsil eden enum değerlerinin bir dizisini kabul eder. Enum değerleri şu deseni izler: camelCase alan adı BÜYÜK HARFE dönüştürülür.

İsimlendirme kuralı:

Sütun adı (DB)Alan adı (GraphQL)GroupBy enum değeri
payment_methodpaymentMethodPAYMENTMETHOD
created_atcreatedAtCREATEDAT
statusstatusSTATUS
category_idcategoryIdCATEGORYID

Örnek: Öğrencileri aktif duruma göre gruplama

Section titled “Örnek: Öğrencileri aktif duruma göre gruplama”

İstek

query {
students(groupBy: [ISACTIVE]) {
items {
isActive
}
count
}
}

Yanıt

{
"data": {
"students": {
"items": [
{ "isActive": true },
{ "isActive": false }
],
"count": 2
}
}
}

aggregateBy argümanı, gruplandırılmış (veya gruplandırılmamış) veriler üzerinde toplama işlevleri hesaplamanıza olanak tanır. Her toplam için bir function, isteğe bağlı bir field ve zorunlu bir alias gerekir.

input {TableName}AggregateInput {
function: AggregateFunction!
field: {TableName}AggregateField
alias: String!
}
İşlevAçıklamafield gerekli mi?
COUNTSatırları saymaHayır (atlandığında COUNT(*) kullanır)
SUMSayısal değerleri toplamaEvet
AVGOrtalama hesaplamaEvet
MINMinimum değer bulmaEvet
MAXMaksimum değer bulmaEvet
COUNT_DISTINCTBenzersiz değerleri saymaEvet

field enum’u GroupBy ile aynı BÜYÜK HARF kuralını izler.

alias, sonucu adlandırmak için seçtiğiniz bir dizedir. aggregates yanıt nesnesinde anahtar olarak görünür.

Örnek: Aktif duruma göre gruplandırılmış öğrencilerin sayısı ve yaş ortalaması

Section titled “Örnek: Aktif duruma göre gruplandırılmış öğrencilerin sayısı ve yaş ortalaması”

İstek

query {
students(
groupBy: [ISACTIVE]
aggregateBy: [
{ function: COUNT, alias: "totalStudents" }
{ function: AVG, field: AGE, alias: "avgAge" }
]
) {
items {
isActive
}
count
aggregates
}
}

Yanıt

{
"data": {
"students": {
"items": [
{ "isActive": true },
{ "isActive": false }
],
"count": 2,
"aggregates": [
{ "totalStudents": 5, "avgAge": 23.4 },
{ "totalStudents": 2, "avgAge": 21.0 }
]
}
}
}

aggregates dizisindeki her giriş, items içindeki aynı indeksteki gruba karşılık gelir.

having argümanı, grupları toplam sonuçlara göre filtreler, SQL’in HAVING cümlesine eşdeğerdir. Üç alanlı özel bir giriş tipi kullanır.

input {TableName}HavingFilterInput {
alias: String!
operator: HavingOperator!
value: Float!
}
  • alias: aggregateBy içinde tanımlanan bir alias ile eşleşmelidir.
  • operator: Karşılaştırma operatörü (aşağıdaki tabloya bakın).
  • value: Karşılaştırılacak sayısal eşik.
OperatörSQL karşılığı
EQUALS=
NOT_EQUALS!=
GREATER_THAN>
GREATER_THAN_OR_EQUAL>=
LESS_THAN<
LESS_THAN_OR_EQUAL<=

Örnek: 3’ten fazla öğrencisi olan şehirler

Section titled “Örnek: 3’ten fazla öğrencisi olan şehirler”

İstek

query {
students(
groupBy: [CITYID]
aggregateBy: [
{ function: COUNT, alias: "studentCount" }
]
having: [
{ alias: "studentCount", operator: GREATER_THAN, value: 3 }
]
) {
items {
cityId
}
count
aggregates
}
}

Yanıt

{
"data": {
"students": {
"items": [
{ "cityId": "e14638cb-6d72-4a36-b30f-9b763136a7bb" }
],
"count": 1,
"aggregates": [
{ "studentCount": 5 }
]
}
}
}

Yalnızca toplam koşulunu karşılayan gruplar döndürülür.

aggregateSort argümanı, gruplandırılmış sonuçları normal bir alan yerine toplam değere göre sıralar.

input {TableName}AggregateSortInput {
alias: String!
direction: SortDirection!
}
  • alias: aggregateBy içinde tanımlanan bir alias ile eşleşmelidir.
  • direction: ASC (artan) veya DESC (azalan).

Örnek: Öğrenci sayısına göre ilk 3 şehir

Section titled “Örnek: Öğrenci sayısına göre ilk 3 şehir”

İstek

query {
students(
groupBy: [CITYID]
aggregateBy: [
{ function: COUNT, alias: "studentCount" }
]
aggregateSort: [
{ alias: "studentCount", direction: DESC }
]
first: 3
) {
items {
cityId
}
count
aggregates
}
}

Yanıt

{
"data": {
"students": {
"items": [
{ "cityId": "e14638cb-6d72-4a36-b30f-9b763136a7bb" },
{ "cityId": "0174dc55-d494-4ebc-a0e9-13575461cad4" },
{ "cityId": "a2b3c4d5-e6f7-8901-2345-678901234567" }
],
"count": 3,
"aggregates": [
{ "studentCount": 5 },
{ "studentCount": 3 },
{ "studentCount": 2 }
]
}
}
}

Karmaşık analizler için tek bir sorguda filter, groupBy, aggregateBy, having, aggregateSort ve first’i birleştirebilirsiniz.

Örnek: Ortalama yaşı 20’nin üzerinde olan aktif öğrencilerin ilk 5 şehri, ortalama yaşa göre sıralanmış

Section titled “Örnek: Ortalama yaşı 20’nin üzerinde olan aktif öğrencilerin ilk 5 şehri, ortalama yaşa göre sıralanmış”

İstek

query {
students(
filter: { isActive: { equals: true } }
groupBy: [CITYID]
aggregateBy: [
{ function: COUNT, alias: "studentCount" }
{ function: AVG, field: AGE, alias: "avgAge" }
{ function: MAX, field: AGE, alias: "maxAge" }
]
having: [
{ alias: "avgAge", operator: GREATER_THAN, value: 20 }
]
aggregateSort: [
{ alias: "avgAge", direction: DESC }
]
first: 5
) {
items {
cityId
}
count
aggregates
}
}

Yanıt

{
"data": {
"students": {
"items": [
{ "cityId": "e14638cb-6d72-4a36-b30f-9b763136a7bb" },
{ "cityId": "0174dc55-d494-4ebc-a0e9-13575461cad4" }
],
"count": 2,
"aggregates": [
{ "studentCount": 3, "avgAge": 24.3, "maxAge": 28 },
{ "studentCount": 2, "avgAge": 22.5, "maxAge": 25 }
]
}
}
}

Bu sorgu:

  1. Filtreler yalnızca aktif öğrencileri (filter).
  2. Gruplar şehre göre (groupBy).
  3. Hesaplar her grupta sayı, ortalama yaş ve maksimum yaş (aggregateBy).
  4. Tutar yalnızca ortalama yaşı 20’nin üzerinde olan grupları (having).
  5. Sıralar ortalama yaşa göre azalan (aggregateSort).
  6. Sınırlar ilk 5 gruba (first).

Toplamalar kullanırken, yanıt ek bir aggregates alanıyla standart Connection tipini izler:

AlanTipAçıklama
items[{TableName}!]!Gruplandırılmış kayıtlar (grup başına bir tane, gruplandırılmış alan değerleriyle)
countInt!Döndürülen grup sayısı
pageInfoPageInfo!Sayfalama bilgisi (hasNextPage, hasPreviousPage)
aggregatesJSONHer biri alias ile indekslenmiş hesaplanan toplam değerleri içeren nesnelerin dizisi

aggregates dizisi items ile paraleldir — indeks i’deki toplam, items içinde indeks i’deki gruba karşılık gelir.

  • GroupBy ve AggregateField enum değerleri camelCase alan adının BÜYÜK HARF kullanır: payment_methodpaymentMethodPAYMENTMETHOD.
  • Having aliasları aggregateBy içinde tanımlanan bir alias ile eşleşmelidir. Eşleşmezse, having koşulu yok sayılır.
  • AggregateSort aliasları aggregateBy içinde tanımlanan bir alias ile eşleşmelidir.
  • Field olmadan COUNT COUNT(*) kullanır, gruptaki tüm satırları sayar.
  • Birden fazla having koşulu birleştirilebilir — hepsi karşılanmalıdır (AND mantığı).
  • Birden fazla aggregateSort girişi öncelik sırasına göre uygulanır (ilk giriş birincil sıralamadır).
  • Standart sayfalama argümanları (first, skip, after, before) gruplandırılmış sonuçlarla çalışır.
  • filter argümanı gruplamadan önce uygulanır (SQL WHERE’e eşdeğer), having ise gruplamadan sonra uygulanır (SQL HAVING’e eşdeğer).