Como classificar o resultado de string_agg ()

98

Eu tenho uma mesa:

CREATE TABLE tblproducts
(
productid integer,
product character varying(20)
)

Com as linhas:

INSERT INTO tblproducts(productid, product) VALUES (1, 'CANDID POWDER 50 GM');
INSERT INTO tblproducts(productid, product) VALUES (2, 'SINAREST P SYP 100 ML');
INSERT INTO tblproducts(productid, product) VALUES (3, 'ESOZ D 20 MG CAP');
INSERT INTO tblproducts(productid, product) VALUES (4, 'HHDERM CREAM 10 GM');
INSERT INTO tblproducts(productid, product) VALUES (5, 'CREAM 15 GM');
INSERT INTO tblproducts(productid, product) VALUES (6, 'KZ LOTION 50 ML');
INSERT INTO tblproducts(productid, product) VALUES (7, 'BUDECORT 200 Rotocap');

Se eu executar string_agg()em tblproducts:

SELECT string_agg(product, ' | ') FROM "tblproducts"

Ele retornará o seguinte resultado:

CANDID POWDER 50 GM | ESOZ D 20 MG CAP | HHDERM CREAM 10 GM | CREAM 15 GM | KZ LOTION 50 ML | BUDECORT 200 Rotocap

Como posso classificar a string agregada, na ordem que usaria ORDER BY product?

Estou usando o PostgreSQL 9.2.4.

Vivek S.
fonte

Respostas:

221

Com o postgres 9.0+ você pode escrever:

select string_agg(product,' | ' order by product) from "tblproducts"

Detalhes aqui .

Igor Romanchenko
fonte
você pode sugerir uma solução que também funcione ao usar funções de janela?
Saurabh Gujarani
Obrigado pelo link. Pesquisar string_aggna documentação não leva você lá.
Manngo
25

https://docs.microsoft.com/en-us/sql/t-sql/functions/string-agg-transact-sql?view=sql-server-2017

SELECT
  STRING_AGG(prod, '|') WITHIN GROUP (ORDER BY product)
FROM ... 
Luuk
fonte
3
A pergunta era sobre PostgreSQL. A WITHIN GROUPcláusula não se aplica à string_aggfunção, como acontece com o Microsoft SQL.
Manngo
5
A pergunta era sobre string_agg. Postgres foi acidental em sua pergunta e ele a mencionou por último. A pergunta também é útil para outras pessoas.
nomen
1
Se esta sintaxe apresentar erros de sintaxe, verifique seu nível de compatibilidade: stackoverflow.com/questions/43611024/…
Sr. TA
4
select string_agg(prod,' | ') FROM 
  (SELECT product as prod FROM tblproducts ORDER BY product )MAIN;

SQL FIDDLE

Ilesh Patel
fonte
2
Eu tive o mesmo problema que o OP, e essa abordagem foi meu primeiro pensamento, mas infelizmente não funciona (o que me trouxe aqui), enquanto o de Igor funciona.
chbrown
Do meu lado, as duas abordagens (de Ilesh e Igor) funcionaram.
Stephan de
2
Resposta errada. Pode funcionar, mas não é garantido que funcione.
zyamys
O banco de dados relacional é baseado em parte em conjuntos matemáticos, e isso se reflete no fato de que um princípio básico em SQL é que a ordem das linhas não é significativa. Mesmo que você inclua uma ORDER BYcláusula na subconsulta, a FROMcláusula não necessariamente coloca os dados em ordem. Se funcionar, é pura sorte.
Manngo
1

Eu estava procurando a mesma solução para o SQL SERVER e encontrei a solução abaixo

SELECT string_agg(product, ' | ') WITHIN GROUP (ORDER BY product) FROM tblproducts
Mveera
fonte