Jak posortować wynik z string_agg ()

100

Mam stolik:

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

Z rzędami:

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

Jeśli wykonam string_agg()na tblproducts:

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

Zwróci następujący wynik:

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

Jak mogę posortować zagregowany ciąg w kolejności, w jakiej bym uzyskał ORDER BY product?

Używam PostgreSQL 9.2.4.

Vivek S.
źródło

Odpowiedzi:

227

Z postgres 9.0+ możesz pisać:

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

Szczegóły tutaj .

Igor Romanchenko
źródło
czy możesz zaproponować rozwiązanie, które sprawdzi się również podczas korzystania z funkcji okna?
Saurabh Gujarani
Dzięki za link. Przeszukiwanie string_aggdokumentacji nie prowadzi Cię tam.
Manngo
32

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
źródło
4
Pytanie dotyczyło PostgreSQL. WITHIN GROUPKlauzula nie ma zastosowania do string_aggfunkcji, jak ma to miejsce w programie Microsoft SQL.
Manngo
6
Pytanie dotyczyło string_agg. Postgres był przypadkowy w stosunku do jego pytania i wspomniał o nim jako ostatni. Pytanie jest przydatne również dla innych.
nomen
1
Jeśli ta składnia powoduje błędy składniowe, sprawdź poziom zgodności: 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
źródło
2
Miałem ten sam problem co OP i takie podejście było moją pierwszą myślą, ale niestety nie działa (co mnie tu sprowadziło), podczas gdy Igor tak.
chbrown
Z mojej strony oba podejścia (Ilesha i Igora) działały.
Stephan
3
Zła odpowiedź. Może działać, ale nie ma gwarancji, że zadziała.
zyamys
Relacyjna baza danych jest częściowo oparta na zbiorach matematycznych, co znajduje odzwierciedlenie w fakcie, że podstawową zasadą języka SQL jest to, że kolejność wierszy nie jest istotna. Nawet jeśli miałbyś dołączyć ORDER BYklauzulę do zapytania podrzędnego, FROMklauzula niekoniecznie zapewnia uporządkowanie danych. Jeśli to zadziała, to czysty przypadek.
Manngo