W PostgreSQL możemy użyć STRING_AGG() funkcja zwracająca kolumny z zapytania w postaci rozdzielanej listy.
Składnia
Składnia wygląda tak:
string_agg ( value text, delimiter text ) → text
string_agg ( value bytea, delimiter bytea ) → bytea
Możemy również użyć ORDER BY klauzula i DISTINCT klauzula z tej funkcji, która wpływa na dane wyjściowe funkcji. Więcej na ten temat poniżej.
Przykład
Załóżmy, że uruchamiamy następujące zapytanie:
SELECT PetName
FROM Pets; I otrzymujemy następujący wynik:
+---------+ | petname | +---------+ | Fluffy | | Fetch | | Scratch | | Wag | | Tweet | | Fluffy | | Bark | | Meow | +---------+ (8 rows)
Możemy użyć STRING_AGG() aby zwrócić wszystkie te wiersze jako listę rozdzielaną.
Aby to zrobić, przekaż PetName kolumna jako pierwszy argument i wybrany przez nas ogranicznik jako drugi argument:
SELECT STRING_AGG(PetName, ',')
FROM Pets; Wynik:
+-------------------------------------------------+ | string_agg | +-------------------------------------------------+ | Fluffy,Fetch,Scratch,Wag,Tweet,Fluffy,Bark,Meow | +-------------------------------------------------+ (1 row)
Zmiana ogranicznika
W poprzednim przykładzie jako ogranicznik wybrałem przecinek. Tutaj jest z innym ogranicznikiem:
SELECT STRING_AGG(PetName, '-')
FROM Pets; Wynik:
Fluffy-Fetch-Scratch-Wag-Tweet-Fluffy-Bark-Meow
Możemy nawet użyć pustego ciągu, aby usunąć wszystkie separatory (aby wartości były połączone):
SELECT STRING_AGG(PetName, '')
FROM Pets; I otrzymujemy następujący wynik:
FluffyFetchScratchWagTweetFluffyBarkMeow
Zamawianie
Możemy użyć ORDER BY klauzula w STRING_AGG() funkcja zamawiania własnego wyjścia:
SELECT STRING_AGG(PetName, ',' ORDER BY PetName ASC) FROM Pets; Wynik:
Bark,Fetch,Fluffy,Fluffy,Meow,Scratch,Tweet,Wag
To było w porządku rosnącym.
Oto w porządku malejącym:
SELECT STRING_AGG(PetName, ',' ORDER BY PetName DESC) FROM Pets; Wynik:
Wag,Tweet,Scratch,Meow,Fluffy,Fluffy,Fetch,Bark
Zauważ, że to sortuje tylko dane wyjściowe STRING_AGG() funkcja – jest całkowicie niezależna od dowolnej kolejności zastosowanej do SELECT samo oświadczenie.
DISTINCT Klauzula
Możemy użyć DISTINCT klauzula zwracająca unikalne wartości. Innymi słowy, jeśli istnieją zduplikowane wartości, zwracane jest tylko jedno wystąpienie:
SELECT STRING_AGG(DISTINCT PetName, ',' ORDER BY PetName ASC) FROM Pets; Wynik:
Bark,Fetch,Fluffy,Meow,Scratch,Tweet,Wag
W tym przypadku Fluffy pojawia się tylko raz. Kiedy uruchamiamy go bez DISTINCT klauzula, Fluffy pojawia się dwukrotnie:
SELECT STRING_AGG(PetName, ',' ORDER BY PetName ASC) FROM Pets; Wynik:
Bark,Fetch,Fluffy,Fluffy,Meow,Scratch,Tweet,Wag
Zgrupowane wyniki zapytań
Możemy dołączyć STRING_AGG() w zapytaniu z GROUP BY klauzula, aby osiągnąć taki wynik:
SELECT
PetTypeId,
STRING_AGG(PetName, ',' ORDER BY PetName ASC)
FROM Pets
GROUP BY PetTypeId
ORDER BY PetTypeId; Wynik:
+-----------+-----------------------+ | pettypeid | string_agg | +-----------+-----------------------+ | 1 | Tweet | | 2 | Fluffy,Meow,Scratch | | 3 | Bark,Fetch,Fluffy,Wag | +-----------+-----------------------+
W mojej bazie danych rzeczywiste nazwy typów zwierząt znajdują się w innej tabeli o nazwie PetTypes . Mogliśmy zatem uruchomić INNER JOIN w PetTypes tabela, aby uzyskać rzeczywiste nazwy typów zwierząt:
SELECT
pt.PetType,
STRING_AGG(p.PetName, ',' ORDER BY p.PetName ASC)
FROM Pets p
INNER JOIN PetTypes pt ON
p.PetTypeId = pt.PetTypeId
GROUP BY pt.PetType
ORDER BY pt.PetType ASC; Wynik:
+---------+-----------------------+ | pettype | string_agg | +---------+-----------------------+ | Bird | Tweet | | Cat | Fluffy,Meow,Scratch | | Dog | Bark,Fetch,Fluffy,Wag | +---------+-----------------------+