Cómo ordenar el resultado de string_agg ()

101

Tengo una mesa:

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

Con las filas:

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 ejecuto string_agg()en tblproducts:

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

Devolverá el siguiente resultado:

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

¿Cómo puedo ordenar la cadena agregada, en el orden en que la usaría ORDER BY product?

Estoy usando PostgreSQL 9.2.4.

Vivek S.
fuente

Respuestas:

227

Con postgres 9.0+ puedes escribir:

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

Detalles aquí .

Igor Romanchenko
fuente
¿Puede sugerir una solución que también funcione al usar funciones de ventana?
Saurabh Gujarani
Gracias por el enlace. Buscar string_aggen la documentación no lo lleva allí.
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
fuente
4
La pregunta era sobre PostgreSQL. La WITHIN GROUPcláusula no se aplica a la string_aggfunción, como ocurre con Microsoft SQL.
Manngo
7
La pregunta era sobre string_agg. Postgres fue incidental a su pregunta y la mencionó en último lugar. La pregunta también es útil para otros.
nomen
1
Si esta sintaxis le da errores de sintaxis, verifique su nivel de compatibilidad: stackoverflow.com/questions/43611024/…
Sr. TA
4
select string_agg(prod,' | ') FROM 
  (SELECT product as prod FROM tblproducts ORDER BY product )MAIN;

Violín SQL

Ilesh Patel
fuente
2
Tuve el mismo problema que OP, y este enfoque fue mi primer pensamiento, pero desafortunadamente no funciona (lo que me trajo aquí), mientras que Igor sí.
chbrown
Por mi parte, ambos enfoques (el de Ilesh y el de Igor) funcionaron.
Stephan
3
Respuesta incorrecta. Podría funcionar, pero no se garantiza que funcione.
zyamys
La base de datos relacional se basa en parte en conjuntos matemáticos, y esto se refleja en el hecho de que un principio básico en SQL es que el orden de las filas no es significativo. Incluso si tuviera que incluir una ORDER BYcláusula en la subconsulta, la FROMcláusula no necesariamente ordena los datos. Si esto funciona, es pura suerte.
Manngo