Comment trier le résultat de string_agg ()

98

J'ai une table:

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

Avec les rangées:

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');

Si j'exécute string_agg()sur tblproducts:

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

Il renverra le résultat suivant:

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

Comment puis-je trier la chaîne agrégée, dans l'ordre que j'utiliserais ORDER BY product?

J'utilise PostgreSQL 9.2.4.

Vivek S.
la source

Réponses:

221

Avec postgres 9.0+, vous pouvez écrire:

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

Détails ici .

Igor Romanchenko
la source
pouvez-vous suggérer une solution qui fonctionnera également lors de l'utilisation des fonctions de fenêtre?
Saurabh Gujarani
Merci pour le lien. La recherche string_aggdans la documentation ne vous y mène pas.
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
la source
3
La question concernait PostgreSQL. La WITHIN GROUPclause ne s'applique pas à la string_aggfonction, comme elle le fait avec Microsoft SQL.
Manngo
5
La question portait sur string_agg. Postgres était accessoire à sa question et il l'a mentionnée en dernier. La question est également utile aux autres.
nomen
1
Si cette syntaxe vous donne des erreurs de syntaxe, vérifiez votre niveau de compatibilité: stackoverflow.com/questions/43611024/...
Mr. TA
4
select string_agg(prod,' | ') FROM 
  (SELECT product as prod FROM tblproducts ORDER BY product )MAIN;

SQL FIDDLE

Ilesh Patel
la source
2
J'ai eu le même problème qu'OP, et cette approche a été ma première pensée, mais malheureusement cela ne fonctionne pas (ce qui m'a amené ici), contrairement à Igor.
chbrown le
De mon côté, les deux approches (d'Ilesh et d'Igor) ont fonctionné.
Stephan
2
Mauvaise réponse. Cela peut fonctionner, mais il n'est pas garanti que cela fonctionne.
zyamys
La base de données relationnelle est basée en partie sur des ensembles mathématiques, et cela se reflète dans le fait qu'un principe de base en SQL est que l'ordre des lignes n'est pas significatif. Même si vous deviez inclure une ORDER BYclause dans la sous-requête, la FROMclause ne met pas nécessairement les données dans l'ordre. Si cela fonctionne, c'est de la pure chance.
Manngo
1

Je cherchais la même solution pour SQL SERVER et j'ai trouvé la solution ci-dessous

SELECT string_agg(product, ' | ') WITHIN GROUP (ORDER BY product) FROM tblproducts
mveera
la source