PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Função STRING_AGG() no PostgreSQL


No PostgreSQL, podemos usar o STRING_AGG() função para retornar colunas de uma consulta como uma lista delimitada.

Sintaxe


A sintaxe fica assim:
string_agg ( value text, delimiter text ) → text
string_agg ( value bytea, delimiter bytea ) → bytea

Também podemos usar o ORDER BY cláusula e um DISTINCT cláusula de dentro desta função, que afeta a saída da função. Mais sobre isso abaixo.

Exemplo


Suponha que executemos a seguinte consulta:
SELECT PetName 
FROM Pets;

E obtemos o seguinte resultado:
+---------+
| petname |
+---------+
| Fluffy  |
| Fetch   |
| Scratch |
| Wag     |
| Tweet   |
| Fluffy  |
| Bark    |
| Meow    |
+---------+
(8 rows)

Podemos usar STRING_AGG() para retornar todas essas linhas como uma lista delimitada.

Para fazer isso, passe o PetName column como o primeiro argumento e nosso delimitador escolhido como o segundo argumento:
SELECT STRING_AGG(PetName, ',') 
FROM Pets;

Resultado:
+-------------------------------------------------+
|                   string_agg                    |
+-------------------------------------------------+
| Fluffy,Fetch,Scratch,Wag,Tweet,Fluffy,Bark,Meow |
+-------------------------------------------------+
(1 row)

Alterando o delimitador


No exemplo anterior, escolhi uma vírgula como delimitador. Aqui está com um delimitador diferente:
SELECT STRING_AGG(PetName, '-') 
FROM Pets;

Resultado:
Fluffy-Fetch-Scratch-Wag-Tweet-Fluffy-Bark-Meow

Podemos até usar uma string vazia para remover todos os separadores (para que os valores sejam concatenados):
SELECT STRING_AGG(PetName, '') 
FROM Pets;

E obtemos o seguinte resultado:
FluffyFetchScratchWagTweetFluffyBarkMeow

Pedidos


Podemos usar o ORDER BY cláusula dentro do STRING_AGG() função para ordenar sua própria saída:
SELECT STRING_AGG(PetName, ',' ORDER BY PetName ASC) FROM Pets;

Resultado:
Bark,Fetch,Fluffy,Fluffy,Meow,Scratch,Tweet,Wag

Isso foi em ordem crescente.

Aqui está em ordem decrescente:
SELECT STRING_AGG(PetName, ',' ORDER BY PetName DESC) FROM Pets;

Resultado:
Wag,Tweet,Scratch,Meow,Fluffy,Fluffy,Fetch,Bark

Observe que isso apenas classifica a saída do STRING_AGG() função – é completamente independente de qualquer ordenação aplicada ao SELECT própria declaração.

O DISTINCT Cláusula


Podemos usar o DISTINCT cláusula para retornar valores exclusivos. Em outras palavras, se houver valores duplicados, apenas uma ocorrência será retornada:
SELECT STRING_AGG(DISTINCT PetName, ',' ORDER BY PetName ASC) FROM Pets;

Resultado:
Bark,Fetch,Fluffy,Meow,Scratch,Tweet,Wag

Neste caso, Fluffy só aparece uma vez. Quando o executamos sem o DISTINCT cláusula, Fluffy aparece duas vezes:
SELECT STRING_AGG(PetName, ',' ORDER BY PetName ASC) FROM Pets;

Resultado:
Bark,Fetch,Fluffy,Fluffy,Meow,Scratch,Tweet,Wag

Resultados da consulta agrupada


Podemos incluir STRING_AGG() em uma consulta com um GROUP BY cláusula para obter um resultado como este:
SELECT 
    PetTypeId,
    STRING_AGG(PetName, ',' ORDER BY PetName ASC)
FROM Pets
GROUP BY PetTypeId
ORDER BY PetTypeId;

Resultado:
+-----------+-----------------------+
| pettypeid |      string_agg       |
+-----------+-----------------------+
|         1 | Tweet                 |
|         2 | Fluffy,Meow,Scratch   |
|         3 | Bark,Fetch,Fluffy,Wag |
+-----------+-----------------------+

No meu banco de dados, os nomes reais dos tipos de animais de estimação estão em outra tabela chamada PetTypes . Portanto, poderíamos executar um INNER JOIN nos PetTypes table para obter os nomes reais dos tipos de animais de estimação:
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;

Resultado:
+---------+-----------------------+
| pettype |      string_agg       |
+---------+-----------------------+
| Bird    | Tweet                 |
| Cat     | Fluffy,Meow,Scratch   |
| Dog     | Bark,Fetch,Fluffy,Wag |
+---------+-----------------------+