Szukam sposobu na połączenie łańcuchów pola w grupie przez zapytanie. Na przykład mam tabelę:
ID COMPANY_ID EMPLOYEE
1 1 Anna
2 1 Bill
3 2 Carol
4 2 Dave
i chciałem pogrupować według company_id, aby uzyskać coś takiego:
COMPANY_ID EMPLOYEE
1 Anna, Bill
2 Carol, Dave
W mySQL jest wbudowana funkcja umożliwiająca wykonanie tego group_concat
Odpowiedzi:
PostgreSQL 9.0 lub nowszy:
Najnowsze wersje Postgres (od końca 2010 r.) Mają
string_agg(expression, delimiter)
funkcję, która wykona dokładnie to, o co pytano, nawet umożliwiając określenie ciągu ogranicznika:Postgres 9.0 dodał także możliwość określenia
ORDER BY
klauzuli w dowolnym wyrażeniu zbiorczym ; w przeciwnym razie kolejność jest niezdefiniowana. Możesz teraz pisać:Lub rzeczywiście:
PostgreSQL 8.4 lub nowszy:
PostgreSQL 8.4 (w 2009 r.) Wprowadził funkcję agregującą,
array_agg(expression)
która łączy wartości w tablicę. Następniearray_to_string()
można go użyć do uzyskania pożądanego rezultatu:string_agg
dla wersji wcześniejszych niż 8.4:W przypadku, gdy ktoś natknie się na to, szukając kompatybilnego podkładki dla baz danych starszych niż 9.0, możliwe jest zaimplementowanie wszystkiego
string_agg
opróczORDER BY
klauzuli.Tak więc w poniższej definicji powinno to działać tak samo, jak w DB Postgres 9.x:
Będzie to jednak błąd składniowy:
Testowany na PostgreSQL 8.3.
Odmiany niestandardowe (wszystkie wersje Postgres)
Przed wersją 9.0 nie było wbudowanej funkcji agregującej do łączenia łańcuchów. Najprostszą niestandardową implementacją ( zasugerowaną przez Vajdę Gabo w tym poście na liście adresowej ) jest użycie wbudowanej
textcat
funkcji (która stoi za||
operatorem):Oto
CREATE AGGREGATE
dokumentacja.To po prostu skleja wszystkie struny razem, bez separatora. Aby wstawić między nimi znak „,” bez konieczności umieszczania go na końcu, możesz utworzyć własną funkcję konkatenacji i zastąpić ją „textcat” powyżej. Oto jeden zestawiłem i testowałem na 8.3.12:
Ta wersja wyświetli przecinek, nawet jeśli wartość w wierszu jest pusta lub pusta, więc otrzymujesz dane wyjściowe w następujący sposób:
Jeśli wolisz usunąć dodatkowe przecinki, aby to wyświetlić:
Następnie dodaj
ELSIF
zaznaczenie do funkcji w następujący sposób:źródło
array_to_string(array_agg(employee), ',')
?Order By
klauzulę wewnątrz funkcji agregującej, np.string_agg(employee, ',' Order By employee)
Co powiesz na korzystanie z wbudowanych funkcji tablicy Postgres? Przynajmniej na 8.4 działa to od razu po wyjęciu z pudełka:
źródło
Począwszy od PostgreSQL 9.0, możesz użyć funkcji agregującej o nazwie string_agg . Twój nowy SQL powinien wyglądać mniej więcej tak:
źródło
Nie żądam uznania za odpowiedź, ponieważ znalazłem ją po kilku poszukiwaniach:
Nie wiedziałem, że PostgreSQL pozwala definiować własne funkcje agregujące za pomocą CREATE AGGREGATE
Ten post na liście PostgreSQL pokazuje, jak proste jest utworzenie funkcji umożliwiającej wykonywanie wymaganych zadań:
źródło
Jak już wspomniano, należy utworzyć własną funkcję agregującą. Oto moja funkcja agregująca konkatenację ( szczegóły w języku francuskim ):
);
A następnie użyj go jako:
źródło
Ten najnowszy fragment listy ogłoszeń może być interesujący, jeśli będziesz aktualizować do wersji 8.4:
Odsyłam link do dokumentów programistycznych 8.4, ale wydaje się, że nie zawierają jeszcze tej funkcji.
źródło
W odpowiedzi na odpowiedź Kev, korzystając z dokumentów Postgres:
Najpierw utwórz tablicę elementów, a następnie użyj wbudowanej
array_to_string
funkcji.źródło
Po raz kolejny na temat korzystania z niestandardowej funkcji agregującej łączenia łańcuchów: musisz pamiętać, że instrukcja select umieści wiersze w dowolnej kolejności, więc będziesz musiał dokonać wyboru podrzędnego w instrukcji from z klauzulą kolejności według i następnie wybierz zewnętrzny z grupą za pomocą klauzuli, aby agregować ciągi, a zatem:
źródło
Uważam, że ta dokumentacja PostgreSQL jest pomocna: http://www.postgresql.org/docs/8.0/interactive/functions-conditional.html .
W moim przypadku szukałem zwykłego SQL-a, aby połączyć pole z nawiasami wokół niego, jeśli pole nie jest puste.
źródło
Użyj
STRING_AGG
funkcji dla PostgreSQL i Google BigQuery SQL :źródło
Zgodnie z wersją PostgreSQL 9.0 i nowszymi możesz użyć funkcji agregującej o nazwie string_agg. Twój nowy SQL powinien wyglądać mniej więcej tak:
źródło
Możesz także użyć funkcji formatowania. Który może również pośrednio zająć się konwersją tekstu, int itp.
źródło
Korzystam z Jetbrains Rider, a kopiowanie wyników z powyższych przykładów w celu ponownego uruchomienia było kłopotliwe, ponieważ wydawało się, że wszystko to zawinęło w JSON. To łączy je w jedną instrukcję, która była łatwiejsza do uruchomienia
źródło
Jeśli korzystasz z Amazon Redshift, gdzie string_agg nie jest obsługiwany, spróbuj użyć listagg.
źródło