# PostgreSQL’de string_agg ile Çoklu Sütun Birleştirme
PostgreSQL veritabanınızda birden fazla sütunu tek bir satıra birleştirmeniz mi gerekiyor? Örneğin, bir müşterinin tüm siparişlerini tek bir satırda göstermek veya bir ürünün tüm özelliklerini tek bir alanda toplamak mı istiyorsunuz? İşte PostgreSQL’in güçlü string_agg fonksiyonunu kullanarak bunu nasıl yapacağınız hakkında adım adım bir rehber. Bu makale, temel seviyeden ileri seviyeye kadar, gerçek dünya örnekleriyle zenginleştirilmiş bir öğrenme yol haritası sunmaktadır. string_agg fonksiyonunu multiple sütunlarla nasıl kullanacağınızı, performans optimizasyonunu ve olası sorunları ele alacağız.
Öğrenme Yol Haritası
Yeni Başlayan: Temel string_agg kullanımı ve basit örnekler.
Orta Seviye: Gerçek dünya senaryoları, performans optimizasyonu ipuçları ve daha karmaşık sorgular.
İleri Seviye: Performans analizi, edge case’ler ve gelişmiş teknikler.
1. Temel Kavramlar: string_agg Fonksiyonu Nedir?
string_agg fonksiyonu, PostgreSQL’de bir gruptaki değerleri tek bir string halinde birleştirmenizi sağlar. Temel sözdizimi şu şekildedir:
string_agg(expression, delimiter)
* expression: Birleştirilecek sütun veya ifade.
* delimiter: Değerler arasındaki ayraç (örneğin, virgül, boşluk, tire).
Örnek: Bir urunler tablosunda ürün isimlerini virgülle ayırarak birleştirmek:
SELECT string_agg(urun_adi, ', ') AS urun_listesi
FROM urunler;
Bu sorgu, urunler tablosundaki tüm ürün isimlerini virgülle ayırarak urun_listesi adlı tek bir sütuna birleştirir.
2. string_agg ile Çoklu Sütunları Birleştirme: Nasıl Yapılır?
string_agg fonksiyonu tek bir sütun için tasarlanmıştır. Ancak, farklı sütunları birleştirmek için || (string birleştirme operatörü) ile birlikte kullanabiliriz. Örneğin, urunler tablosunda ürün adını ve fiyatını birleştirmek için:
SELECT string_agg(urun_adi || ' - ' || urun_fiyati::text, ', ') AS urun_bilgileri
FROM urunler;
Bu sorgu, her ürünün adını ve fiyatını ” – ” ile ayırarak birleştirir ve sonuçları virgülle ayırır. urun_fiyati::text kısmı, sayısal urun_fiyati sütununu string’e dönüştürmek için kullanılır.
3. Gerçek Dünya Örneği: Müşteri Siparişleri
Bir e-ticaret sitesinin veritabanında, her müşterinin siparişlerini tek bir satırda göstermek istediğimizi varsayalım. musteriler ve siparisler tablolarımız olsun:
musteriler tablosu:
| musteri_id | musteri_adi |
|—|—|
| 1 | Ahmet Yılmaz |
| 2 | Ayşe Kaya |
siparisler tablosu:
| siparis_id | musteri_id | urun_adi | siparis_tarihi |
|—|—|—|—|
| 1 | 1 | Kitap | 2024-03-08 |
| 2 | 1 | Kalem | 2024-03-10 |
| 3 | 2 | Defter | 2024-03-15 |
Aşağıdaki sorgu, her müşterinin sipariş bilgilerini tek bir satırda gösterir:
SELECT
m.musteri_adi,
string_agg(s.urun_adi || ' (' || s.siparis_tarihi::text || ')', ', ') AS siparisler
FROM
musteriler m
JOIN
siparisler s ON m.musteri_id = s.musteri_id
GROUP BY
m.musteri_adi;
Bu sorgu, musteriler ve siparisler tablolarını musteri_id sütununa göre birleştirir ve her müşteri için string_agg fonksiyonunu kullanarak sipariş bilgilerini birleştirir.
4. Performans Optimizasyonu İpuçları
Çok büyük tablolarla çalışırken string_agg performans sorunlarına yol açabilir. İşte bazı optimizasyon ipuçları:
* İndeksler: GROUP BY ile kullanılan sütunlara indeks eklemek sorgu performansını önemli ölçüde artırabilir.
* WHERE klauzu: Gerekli verileri filtrelemek için WHERE klauzu kullanın. Tüm tabloyu işlemek yerine sadece ilgili veriler üzerinde çalışmak daha hızlıdır.
* Alt Sorgular: Karmaşık sorgularda, alt sorgular yerine JOIN kullanmak daha verimli olabilir.
* LIMIT klauzu: Çok fazla veri varsa, LIMIT klauzu kullanarak sonuç kümesini sınırlayabilirsiniz.
* Parçalı İşleme: Çok büyük tablolar için, verileri daha küçük parçalara bölerek işlemek ve sonuçları birleştirmek daha etkili olabilir. Bu, özellikle büyük gruplarla çalışırken faydalıdır.
5. İleri Düzey Teknikler: JSON Kullanımı
Çoklu sütunları birleştirmenin daha esnek bir yolu, JSON kullanmaktır. JSON, daha karmaşık veri yapılarını tek bir alanda saklamanıza olanak tanır.
SELECT
m.musteri_adi,
json_agg(json_build_object('urun_adi', s.urun_adi, 'siparis_tarihi', s.siparis_tarihi)) AS siparisler
FROM
musteriler m
JOIN
siparisler s ON m.musteri_id = s.musteri_id
GROUP BY
m.musteri_adi;
Bu sorgu, her müşterinin siparişlerini bir JSON dizisi olarak birleştirir. Bu yaklaşım, daha fazla veriyi tek bir alanda saklamak ve daha sonra kolayca işlemek için daha uygun olabilir. Daha fazla bilgi için [Fatih Soysal’ın PostgreSQL JSON rehberine](https://fatihsoysal.com/postgresql-json-rehberi/) bakabilirsiniz (burası örnek bir bağlantıdır, gerçek bir bağlantı eklenmelidir).
6. Edge Case’ler ve Hata Ayıklama
* NULL Değerler: string_agg fonksiyonu NULL değerleri dikkate almaz. NULL değerleri içeren sütunları birleştirmeden önce bunları boş string (“”) ile değiştirmeniz gerekebilir.
* Çok Büyük Stringler: Çok büyük stringler oluşturmak performans sorunlarına ve hata mesajlarına yol açabilir. String uzunluğunu sınırlamak için fonksiyonlar kullanabilirsiniz.
* Karakter Kodlaması: Farklı karakter kodlamaları kullanan sütunları birleştirirken sorunlar yaşayabilirsiniz. Karakter kodlamalarını kontrol edin ve gerektiğinde dönüştürme yapın.
7. Performans Analizi ve Optimizasyon
EXPLAIN ANALYZE komutu, sorgunuzun performansını analiz etmenize yardımcı olur. Bu komutu kullanarak sorgunuzun hangi aşamalarında zaman harcadığını ve hangi indekslerin kullanıldığını görebilirsiniz. Sonuçları inceleyerek, sorgunuzu optimize etmek için gereken adımları belirleyebilirsiniz. Örneğin, indeks eklemek veya farklı bir sorgu stratejisi kullanmak performansı artırabilir.
8. Gerçek Dünya Senaryosu: Ürün Özellikleri
Bir ürün kataloğunda her ürünün özelliklerini tek bir alanda birleştirmek isteyelim. urunler ve ozellikler tablolarımız olsun:
urunler tablosu:
| urun_id | urun_adi |
|—|—|
| 1 | Telefon |
| 2 | Tablet |
ozellikler tablosu:
| ozellik_id | urun_id | ozellik_adi | ozellik_degeri |
|—|—|—|—|
| 1 | 1 | Renk | Siyah |
| 2 | 1 | Hafıza | 128GB |
| 3 | 2 | Renk | Gri |
| 4 | 2 | Hafıza | 64GB |
Aşağıdaki sorgu, her ürünün özelliklerini JSON formatında birleştirir:
SELECT
u.urun_adi,
json_agg(json_build_object('ozellik_adi', o.ozellik_adi, 'ozellik_degeri', o.ozellik_degeri)) AS ozellikler
FROM
urunler u
JOIN
ozellikler o ON u.urun_id = o.urun_id
GROUP BY
u.urun_adi;
Sonuç
string_agg fonksiyonu, PostgreSQL’de çoklu sütunları tek bir string halinde birleştirmek için güçlü bir araçtır. Ancak, büyük tablolarla çalışırken performans sorunlarına dikkat etmek önemlidir. İndeksler, WHERE klauzu, alt sorguların optimizasyonu ve JSON kullanımı gibi teknikler, performansı artırmaya yardımcı olabilir. Bu makalede ele alınan örnekler ve teknikler, farklı senaryolarda string_agg fonksiyonunu etkin bir şekilde kullanmanıza yardımcı olacaktır.
Sıkça Sorulan Sorular:
1. string_agg fonksiyonu NULL değerleri nasıl ele alır? NULL değerleri dikkate almaz.
2. Çok büyük stringler oluşturmaktan nasıl kaçınılır? String uzunluğunu sınırlamak için fonksiyonlar kullanın.
3. string_agg fonksiyonunun performansını nasıl optimize ederim? İndeksler, WHERE klauzu ve alt sorguların optimizasyonu ile.
4. Farklı karakter kodlamaları kullanan sütunları birleştirirken sorun yaşarsam ne yapmalıyım? Karakter kodlamalarını kontrol edin ve gerektiğinde dönüştürme yapın.
5. string_agg yerine JSON kullanmanın avantajları nelerdir? Daha karmaşık veri yapılarını tek bir alanda saklama ve daha kolay işleme imkanı sağlar.
Yazar: Fatih Soysal
