PostgreSQL 9.0 veya üstü:
Postgres'in son sürümleri (2010'un sonlarından beri), string_agg(expression, delimiter)
sorulan soruyu tam olarak yapacak ve hatta sınırlayıcı dizesini belirtmenize izin veren bir işleve sahiptir:
SELECT company_id, string_agg(employee, ', ')
FROM mytable
GROUP BY company_id;
Postgres 9.0 ayrıca herhangi bir toplu ifadede bir ORDER BY
cümle belirtme yeteneğini de ekledi ; aksi takdirde sipariş tanımsızdır. Şimdi yazabilirsiniz:
SELECT company_id, string_agg(employee, ', ' ORDER BY employee)
FROM mytable
GROUP BY company_id;
Ya da gerçekten:
SELECT string_agg(actor_name, ', ' ORDER BY first_appearance)
PostgreSQL 8.4 veya üzeri:
PostgreSQL 8.4 (2009'da) , değerleri bir diziye birleştiren toplama işleviniarray_agg(expression)
tanıttı . Daha sonra array_to_string()
istenen sonucu vermek için kullanılabilir:
SELECT company_id, array_to_string(array_agg(employee), ', ')
FROM mytable
GROUP BY company_id;
string_agg
8.4 öncesi sürümler için:
Herkesin 9.0 öncesi veritabanları için uyumluluk şim aramasıyla karşılaşması durumunda string_agg
, ORDER BY
madde hariç her şeyi uygulamak mümkündür .
Aşağıdaki tanım ile bu 9.x Postgres DB ile aynı çalışmalıdır:
SELECT string_agg(name, '; ') AS semi_colon_separated_names FROM things;
Ancak bu bir sözdizimi hatası olacaktır:
SELECT string_agg(name, '; ' ORDER BY name) AS semi_colon_separated_names FROM things;
--> ERROR: syntax error at or near "ORDER"
PostgreSQL 8.3 üzerinde test edilmiştir.
CREATE FUNCTION string_agg_transfn(text, text, text)
RETURNS text AS
$$
BEGIN
IF $1 IS NULL THEN
RETURN $2;
ELSE
RETURN $1 || $3 || $2;
END IF;
END;
$$
LANGUAGE plpgsql IMMUTABLE
COST 1;
CREATE AGGREGATE string_agg(text, text) (
SFUNC=string_agg_transfn,
STYPE=text
);
Özel varyasyonlar (tüm Postgres sürümleri)
9.0'dan önce, dizeleri birleştirmek için yerleşik bir toplama işlevi yoktu. En basit özel uygulama ( Vajda Gabo tarafından bu posta listesi postasında , diğerleri arasında önerilmektedir ) yerleşik textcat
işlevi kullanmaktır ( ||
operatörün arkasında bulunur ):
CREATE AGGREGATE textcat_all(
basetype = text,
sfunc = textcat,
stype = text,
initcond = ''
);
İşte CREATE AGGREGATE
belgeler.
Bu, tüm dizeleri ayırıcı olmadan birleştirir. Sonuna sahip olmadan aralarına bir "," eklemek için, kendi birleştirme işlevinizi yapmak ve yukarıdaki "textcat" yerine koymak isteyebilirsiniz. İşte 8.3.12 üzerinde bir araya getirip test ettiğim:
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 sürüm, satırdaki değer null veya boş olsa bile virgül üretir, böylece şöyle çıktı alırsınız:
a, b, c, , e, , g
Bunun çıktısını almak için fazladan virgül kullanmayı tercih ediyorsanız:
a, b, c, e, g
Ardından ELSIF
, işleve şu şekilde bir kontrol ekleyin :
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;