В PostgreSQL можем да използваме STRING_AGG()
функция за връщане на колони от заявка като разделен списък.
Синтаксис
Синтаксисът е така:
string_agg ( value text, delimiter text ) → text
string_agg ( value bytea, delimiter bytea ) → bytea
Можем също да използваме ORDER BY
клауза и DISTINCT
клауза от тази функция, която засяга изхода от функцията. Повече за това по-долу.
Пример
Да предположим, че изпълняваме следната заявка:
SELECT PetName
FROM Pets;
И получаваме следния резултат:
+---------+ | petname | +---------+ | Fluffy | | Fetch | | Scratch | | Wag | | Tweet | | Fluffy | | Bark | | Meow | +---------+ (8 rows)
Можем да използваме STRING_AGG()
за да върнете всички тези редове като разделен списък.
За да направите това, предайте PetName
колона като първи аргумент и избраният от нас разделител като втори аргумент:
SELECT STRING_AGG(PetName, ',')
FROM Pets;
Резултат:
+-------------------------------------------------+ | string_agg | +-------------------------------------------------+ | Fluffy,Fetch,Scratch,Wag,Tweet,Fluffy,Bark,Meow | +-------------------------------------------------+ (1 row)
Промяна на разделителя
В предишния пример избрах запетая като разделител. Ето го с различен разделител:
SELECT STRING_AGG(PetName, '-')
FROM Pets;
Резултат:
Fluffy-Fetch-Scratch-Wag-Tweet-Fluffy-Bark-Meow
Можем дори да използваме празен низ, за да премахнем всички разделители (така че стойностите да са свързани):
SELECT STRING_AGG(PetName, '')
FROM Pets;
И получаваме следния резултат:
FluffyFetchScratchWagTweetFluffyBarkMeow
Поръчка
Можем да използваме ORDER BY
клауза в STRING_AGG()
функция за подреждане на собствен изход:
SELECT STRING_AGG(PetName, ',' ORDER BY PetName ASC) FROM Pets;
Резултат:
Bark,Fetch,Fluffy,Fluffy,Meow,Scratch,Tweet,Wag
Това беше във възходящ ред.
Ето го в низходящ ред:
SELECT STRING_AGG(PetName, ',' ORDER BY PetName DESC) FROM Pets;
Резултат:
Wag,Tweet,Scratch,Meow,Fluffy,Fluffy,Fetch,Bark
Имайте предвид, че това сортира само изхода на STRING_AGG()
функция – тя е напълно независима от всяка подредба, приложена към SELECT
самото изявление.
DISTINCT
Клауза
Можем да използваме DISTINCT
клауза за връщане на уникални стойности. С други думи, ако има дублиращи се стойности, се връща само едно събитие:
SELECT STRING_AGG(DISTINCT PetName, ',' ORDER BY PetName ASC) FROM Pets;
Резултат:
Bark,Fetch,Fluffy,Meow,Scratch,Tweet,Wag
В този случай Fluffy
се появява само веднъж. Когато го стартираме без DISTINCT
клауза, Fluffy
се появява два пъти:
SELECT STRING_AGG(PetName, ',' ORDER BY PetName ASC) FROM Pets;
Резултат:
Bark,Fetch,Fluffy,Fluffy,Meow,Scratch,Tweet,Wag
Резултати от групирани заявки
Можем да включим STRING_AGG()
в заявка с GROUP BY
клауза за постигане на резултат като този:
SELECT
PetTypeId,
STRING_AGG(PetName, ',' ORDER BY PetName ASC)
FROM Pets
GROUP BY PetTypeId
ORDER BY PetTypeId;
Резултат:
+-----------+-----------------------+ | pettypeid | string_agg | +-----------+-----------------------+ | 1 | Tweet | | 2 | Fluffy,Meow,Scratch | | 3 | Bark,Fetch,Fluffy,Wag | +-----------+-----------------------+
В моята база данни действителните имена на типове домашни любимци са в друга таблица, наречена PetTypes
. Следователно бихме могли да изпълним INNER JOIN
на PetTypes
таблица, за да получите действителните имена на домашни любимци:
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;
Резултат:
+---------+-----------------------+ | pettype | string_agg | +---------+-----------------------+ | Bird | Tweet | | Cat | Fluffy,Meow,Scratch | | Dog | Bark,Fetch,Fluffy,Wag | +---------+-----------------------+