1. Toplam Analiz Girişi
Toplama işlemi, veritabanı sorgularında çok önemli bir kavramdır. Genellikle toplama, sayma, ortalama, maksimum ve minimum değerler gibi istatistiksel analizler için kullanılır. Bu işlemler, kullanıcılara büyük miktarda veriden anlamlı bilgiler çıkarmalarına yardımcı olarak veri analizi ve karar verme desteği sağlar. Veritabanında toplama için uygulanan işlevler genellikle toplama işlevleri olarak adlandırılır.
2. Temel Toplama İşlemleri
2.1. Toplama İşlevlerinin Kavramı
Toplama işlevleri, veritabanı sorgu dillerinde kullanılan ve bir dizi hesaplama gerçekleştiren ve tek bir değer döndüren işlevlerdir. SQL ve benzeri sorgu dillerinde, toplama işlevleri veri sütunu üzerinde işlem yapabilir ve toplam (SUM), ortalama (AVG), sayma (COUNT), maksimum (MAX) ve minimum (MIN) gibi tek bir değer döndürebilir. Veri istatistiksel analizi gerçekleştirmemiz gerektiğinde, toplama işlevleri veri kümelerini işlemek ve istatistiksel veri çıkarmak için önemli araçlardır.
2.2. Tek-Alanlı Toplama
Pratik uygulamalarda, tek-alanlı toplama analizi çok yaygın bir gereksinimdir ve genellikle belirli bir sütunun toplamı, ortalaması, maksimum ve minimum değerleri gibi istatistiksel sonuçları elde etmek için kullanılır. Diyelim ki ödeme bilgisi tablomuz var ve kullanıcıların ödediği toplam tutarı hesaplamak istiyoruz. ent
çatısı kullanarak, varlıktan sorgu oluşturabilir ve toplama işlevlerini aşağıdaki gibi uygulayabiliriz:
func Yap(ctx context.Context, client *ent.Client) {
// Ödeme varlığı için Miktar alanının toplamını hesapla
toplam, err := client.Payment.Query().
Aggregate(
ent.Sum(payment.Amount),
).
Int(ctx)
if err != nil {
log.Fatalf("Toplam alınamadı: %v", err)
}
log.Printf("Ödemelerin toplam tutarı: %d", toplam)
}
Yukarıdaki kod örneğinde, client.Payment.Query()
kullanarak ödeme varlığı için bir sorgu başlatırız, ardından Aggregate()
yöntemini kullanarak parametre olarak payment.Amount
ile ent.Sum
işlevini çağırarak ödemelerin toplam tutarını hesaplarız. Sonra sonucu bir tamsayıya dönüştürmek için .Int(ctx)
kullanır ve kaydederiz.
2.3. Çok-Alanlı Toplama
Birçok durumda, sadece bir alanda değil, birden çok alanda toplama işlemleri gerçekleştirmemiz gerekebilir. Bu bölümde, bir örnek üzerinden çok-alanlı toplamayı nasıl gerçekleştireceğimizi göstereceğiz.
Bu örnekte, evcil hayvan tablosundaki Yaş
alanının toplamını bulup, minimumunu, maksimumunu ve sayısını bulacağız.
func Yap(ctx context.Context, client *ent.Client) {
var v []struct {
Toplam, Min, Max, Sayı int
}
err := client.Pet.Query().
Aggregate(
ent.Sum(pet.FieldAge), // Yaşın toplamı
ent.Min(pet.FieldAge), // Minimum Yaş
ent.Max(pet.FieldAge), // Maksimum Yaş
ent.Count(), // Sayma
).
Scan(ctx, &v)
if err != nil {
log.Fatalf("Sorgu başarısız: %v", err)
}
// Tüm toplama sonuçlarını çıktıla
for _, toplam := range v {
fmt.Printf("Toplam: %d Min: %d Max: %d Sayı: %d\n", toplam.Toplam, toplam.Min, toplam.Max, toplam.Sayı)
}
}
Yukarıdaki kodda, çok-alanlı toplama işlemi için Aggregate
işlevini kullanır ve sonuçları v
dilimine kaydetmek için Scan
işlevini kullanırız. Sonra, v
üzerinde dolaşarak tüm toplama sonuçlarını çıktılarız.
3. Gruplandırma Toplama Uygulaması
3.1. Alanları Gruplamak İçin Group By Kullanımı
Veritabanı işlemlerinde, Group By
, verileri gruplamak için yaygın bir yöntemdir. Bu bölümde, veritabanındaki verileri gruplamak için Group By
'ı nasıl kullanacağımızı öğreneceğiz.
Gruplandırılmış sorgu çalıştırmak için bir veya daha fazla alanı nasıl gruplayacağımızı anlatan öğretici örnek.
Varsayalım ki bir kullanıcı tablomuz var ve kullanıcıların ad
alanını gruplandırmamız ve her grup için kullanıcı sayısını hesaplamamız gerekiyor. Aşağıda, bu gereksinimi nasıl karşılayacağımızın bir kod örneği bulunmaktadır:
func Yap(ctx context.Context, client *ent.Client) {
isimler, err := client.User.
Query().
GroupBy(user.FieldName).
Strings(ctx)
if err != nil {
log.Fatalf("Gruplu sorgu çalıştırılamadı: %v", err)
}
// Her grubun adını çıktıla
for _, isim := range isimler {
fmt.Println("Grup adı:", isim)
}
}
Yukarıdaki kodda, sorgu oluşturucunun GroupBy
yöntemini kullanarak hangi alanı gruplamak istediğimizi belirtiriz.
3.2. Birden Fazla Alanı Gruplama ve Toplama
Bazı durumlarda, verileri birden fazla alana göre gruplamak ve her bir grupta toplama işlemleri gerçekleştirmek isteyebiliriz. Aşağıda, bu gereksinimi nasıl karşılayacağımızın bir örneği bulunmaktadır:
Aşağıdaki kod, kullanıcı tablosundaki verileri name
ve age
alanlarına göre gruplamak ve her bir grupta toplam yaş ve kullanıcı sayısını hesaplamak için nasıl kullanılacağını göstermektedir.
func Yap(ctx context.Context, client *ent.Client) {
var v []struct {
Name string `json:"name"`
Age int `json:"age"`
Sum int `json:"sum"`
Count int `json:"count"`
}
err := client.User.Query().
GroupBy(user.FieldName, user.FieldAge).
Aggregate(ent.Count(), ent.Sum(user.FieldAge)).
Scan(ctx, &v)
if err != nil {
log.Fatalf("Birden fazla alana göre gruplama ve toplama sorgusunu çalıştırmada başarısız oldu: %v", err)
}
// Her bir grup için detaylı bilgileri yazdır
for _, group := range v {
fmt.Printf("Ad: %s Yaş: %d Toplam: %d Sayı: %d\n", group.Name, group.Age, group.Sum, group.Count)
}
}
Bu örnekte, kullanıcı tablosundaki verileri sadece name
ve age
alanlarına göre değil, aynı zamanda her bir grupta toplam kayıt sayısını ve toplam yaşın hesaplanması için Count
ve Sum
toplama işlevlerinin de kullanıldığı gösterilmektedir.
4. Gruplama ile Having'in Birleştirilmesi
Having
ifadesi, Group By
işleminden sonra elde edilen toplama sonuçlarını filtreler. Aşağıdaki örnek, her roldeki maksimum yaşa sahip kullanıcıları yalnızca seçmenin nasıl yapıldığını göstermektedir:
func Yap(ctx context.Context, client *ent.Client) {
var users []struct {
Id Int
Age Int
Role string
}
err := client.User.Query().
Modify(func(s *sql.Selector) {
s.GroupBy(user.FieldRole)
s.Having(
sql.EQ(
user.FieldAge,
sql.Raw(sql.Max(user.FieldAge)),
),
)
}).
ScanX(ctx, &users)
if err != nil {
log.Fatalf("Gruplama ile birleştirilmiş Having sorgusunu çalıştırmada başarısız oldu: %v", err)
}
// Having koşulunu sağlayan kullanıcı bilgilerini yazdır
for _, user := range users {
fmt.Printf("ID: %d Yaş: %d Rol: %s\n", user.Id, user.Age, user.Role)
}
}
Yukarıdaki kod, her roldeki maksimum yaşa sahip kullanıcıları seçmek için karşılık gelen bir SQL sorgusu oluşturacaktır.