PostgreSQL Grup By Sorgusunda Dize Birleştirmenin Yöntemi

Veritabanlarıyla çalışırken, özellikle PostgreSQL ile, kayıtlar grubundaki dizeleri birleştirmeniz gereken yaygın bir senaryo ile karşılaşabilirsiniz. Bu genellikle, aynı kategoriye ait birden fazla giriş içeren bir veri kümesi ile çalıştığınızda (örneğin, aynı şirketteki çalışanlar) ve bu girişleri sunum veya analiz için tek bir dizeye toplamak istediğinizde ortaya çıkar.

Bu blog yazısında, PostgreSQL’de GROUP BY sorgusu ile dize birleştirmenin nasıl gerçekleştirileceğini açıklayacağız. Hem modern çözümleri hem de daha eski PostgreSQL sürümleri için yaklaşımları kapsamlı bir anlayış sağlaması açısından ele alacağız.

Sorun

Örneğin, aşağıdaki çalışanlar tablosunu düşünün:

ID COMPANY_ID ÇALIŞAN
1 1 Anna
2 1 Bill
3 2 Carol
4 2 Dave

Bu girişleri COMPANY_ID ile gruplamak istiyorsanız, çıktı her şirketle ilişkili çalışanların listesini sunacak şekilde olmalıdır. İstenen çıktı şöyle olacaktır:

COMPANY_ID ÇALIŞAN
1 Anna, Bill
2 Carol, Dave

Çözüm

PostgreSQL 9.0 veya Daha Yeni Sürümler

Eğer PostgreSQL 9.0 veya daha yeni bir sürüm kullanıyorsanız, dize birleştirmek için GROUP BY ifadesinde etkili bir şekilde kullanabileceğiniz yerleşik string_agg() fonksiyonunu kullanabilirsiniz.

Sorguyu şu şekilde yazabilirsiniz:

SELECT company_id, string_agg(employee, ', ')
FROM mytable
GROUP BY company_id;

Sıralama ile

Ayrıca, PostgreSQL 9.0’dan itibaren toplama fonksiyonları içinde ORDER BY desteği olduğundan, çalışanların sırasını belirtin:

SELECT company_id, string_agg(employee, ', ' ORDER BY employee)
FROM mytable
GROUP BY company_id;

Bu, çalışan adlarınızın belirli bir sırada birleştirilmesini sağlar.

PostgreSQL 8.4.x

Eğer hala PostgreSQL 8.4 ile çalışıyorsanız, artık destek almayan bu sürümde, benzer sonuçlar elde etmek için array_agg() fonksiyonunu array_to_string() ile bir arada kullanabilirsiniz. İşte kullanacağınız SQL sorgusu:

SELECT company_id, array_to_string(array_agg(employee), ', ')
FROM mytable
GROUP BY company_id;

PostgreSQL 8.3.x ve Daha Eski Sürümler

PostgreSQL 8.3 ve daha eski sürümlerde, dize birleştirmek için doğrudan kullanılabilecek bir yerleşik fonksiyon yoktur. Aşağıdaki özel uygulama bu sınırlamanın üstesinden gelebilir:

  1. textcat fonksiyonu kullanarak yeni bir toplama fonksiyonu oluşturun:
CREATE AGGREGATE textcat_all(
  basetype    = text,
  sfunc       = textcat,
  stype       = text,
  initcond    = ''
);
  1. Birleştirilmiş dizelerin arasına , gibi ayırıcılar eklemek için özel bir fonksiyon oluşturun:
CREATE FUNCTION commacat(acc text, instr text) RETURNS text AS $$
BEGIN
  IF acc IS NULL OR acc = '' THEN
    RETURN instr;
  ELSE
    RETURN acc || ', ' || instr;
  END IF;
END;
$$ LANGUAGE plpgsql;

Bu, dizeleri uygun bir şekilde birleştirecektir.

Eğer NULL veya boş değerler için ekstra virgülleri kaldırmak istiyorsanız, işte daha rafine bir versiyon:

CREATE FUNCTION commacat_ignore_nulls(acc text, instr text) RETURNS text AS $$
BEGIN
  IF acc IS NULL OR acc = '' THEN
    RETURN instr;
  ELSIF instr IS NULL OR instr = '' THEN
    RETURN acc;
  ELSE
    RETURN acc || ', ' || instr;
  END IF;
END;
$$ LANGUAGE plpgsql;

Sonuç

PostgreSQL’de dize birleştirmek, özellikle GROUP BY işlemleri sırasında anlamlı raporlar ve veri setleri oluşturmak için önemli bir işlemdir. Son sürümlerde string_agg() gibi fonksiyonların kullanılmasıyla, bu görev oldukça basit hale gelmiştir.

Eski bir sürümü kullanıyorsanız, burada açıklanan özel toplama yöntemlerini kullanarak benzer sonuçlar elde edebilirsiniz. Her zaman PostgreSQL sürümünüzü güncelleyerek daha yeni özelliklerden ve güvenlik iyileştirmelerinden faydalanmayı düşünün.

İyi sorgulamalar!