PostgreSQL 9.0 lub nowszy:
Nowoczesny Postgres (od 2010) ma string_agg(expression, delimiter)
funkcja, która zrobi dokładnie to, czego szukał pytający:
SELECT company_id, string_agg(employee, ', ')
FROM mytable
GROUP BY company_id;
Postgres 9 dodał również możliwość określenia ORDER BY
klauzula w dowolnym wyrażeniu zagregowanym; w przeciwnym razie musisz uporządkować wszystkie wyniki lub zająć się niezdefiniowaną kolejnością. Możesz więc teraz pisać:
SELECT company_id, string_agg(employee, ', ' ORDER BY employee)
FROM mytable
GROUP BY company_id;
PostgreSQL 8.4.x:
PostgreSQL 8.4 (w 2009) wprowadził funkcję agregującą array_agg(expression)
który zbiera wartości w tablicy. Następnie array_to_string()
może być użyty do uzyskania pożądanego rezultatu:
SELECT company_id, array_to_string(array_agg(employee), ', ')
FROM mytable
GROUP BY company_id;
PostgreSQL 8.3.x i starsze:
Kiedy to pytanie było pierwotnie postawione, nie było wbudowanej funkcji agregującej do łączenia ciągów. Najprostszą niestandardową implementacją (sugerowaną przez Vajdę Gabo w tym poście na liście dyskusyjnej, między innymi, między innymi) jest użycie wbudowanego textcat
funkcja (która leży za ||
operator):
CREATE AGGREGATE textcat_all(
basetype = text,
sfunc = textcat,
stype = text,
initcond = ''
);
Oto CREATE AGGREGATE
dokumentacja.
To po prostu skleja wszystkie struny ze sobą, bez separatora. Aby wstawić „,” między nimi bez umieszczania go na końcu, możesz utworzyć własną funkcję konkatenacji i zastąpić ją „textcat” powyżej. Oto jeden, który złożyłem i przetestowałem w 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;
Ta wersja wypisze przecinek, nawet jeśli wartość w wierszu jest pusta lub pusta, więc otrzymujesz dane wyjściowe w następujący sposób:
a, b, c, , e, , g
Jeśli wolisz usunąć dodatkowe przecinki, aby to wypisać:
a, b, c, e, g
Następnie dodaj ELSIF
sprawdź funkcję w następujący sposób:
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;