PostgreSQL 9.0 или по-нова версия:
Съвременният Postgres (от 2010 г.) има string_agg(expression, delimiter)
функция, която ще направи точно това, което питащият е търсил:
SELECT company_id, string_agg(employee, ', ')
FROM mytable
GROUP BY company_id;
Postgres 9 също добави възможността за указване на ORDER BY
клауза във всеки обобщен израз; в противен случай трябва да поръчате всичките си резултати или да се справите с недефинирана поръчка. Така че вече можете да пишете:
SELECT company_id, string_agg(employee, ', ' ORDER BY employee)
FROM mytable
GROUP BY company_id;
PostgreSQL 8.4.x:
PostgreSQL 8.4 (през 2009 г.) въведе агрегатната функция array_agg(expression)
който събира стойностите в масив. След това array_to_string()
може да се използва за получаване на желания резултат:
SELECT company_id, array_to_string(array_agg(employee), ', ')
FROM mytable
GROUP BY company_id;
PostgreSQL 8.3.x и по-стари:
Когато първоначално беше зададен този въпрос, нямаше вградена агрегатна функция за конкатенация на низове. Най-простата персонализирана реализация (предложена от Vajda Gabo в тази публикация в пощенския списък, наред с много други) е да се използва вграденият textcat
функция (която се намира зад ||
оператор):
CREATE AGGREGATE textcat_all(
basetype = text,
sfunc = textcat,
stype = text,
initcond = ''
);
Ето CREATE AGGREGATE
документация.
Това просто залепва всички струни заедно, без разделител. За да получите ", " вмъкнат между тях, без да го имате в края, може да искате да направите своя собствена функция за конкатенация и да я замените с "textcat" по-горе. Ето един, който съставих и тествах на 8.3.12:
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;
Тази версия ще изведе запетая, дори ако стойността в реда е нула или празна, така че ще получите резултат по следния начин:
a, b, c, , e, , g
Ако предпочитате да премахнете допълнителни запетаи, за да изведете това:
a, b, c, e, g
След това добавете ELSIF
проверете функцията по следния начин:
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;