“All products per customer, comma-separated.” Every engine can do it; the function name differs.
-- PostgreSQL, BigQuery, DuckDB
SELECT customer_id, STRING_AGG(product, ', ' ORDER BY product) AS products
FROM orders GROUP BY customer_id;
-- MySQL
SELECT customer_id, GROUP_CONCAT(product ORDER BY product SEPARATOR ', ') AS products
FROM orders GROUP BY customer_id;
-- SQLite (separator is the 2nd arg; ORDER BY needs 3.44+)
SELECT customer_id, GROUP_CONCAT(product, ', ') AS products
FROM orders GROUP BY customer_id;
-- Snowflake
SELECT customer_id, LISTAGG(product, ', ') WITHIN GROUP (ORDER BY product) AS products
FROM orders GROUP BY customer_id;
Two traps.
- MySQL silently truncates at
group_concat_max_len(default 1024 bytes). Raise it for long lists:SET SESSION group_concat_max_len = 1000000;.- Ordering isn’t guaranteed unless you ask. Put
ORDER BYinside the aggregate (as shown). SQLite’sGROUP_CONCATonly accepts anORDER BYargument from version 3.44; on older SQLite, order in a subquery first.
Distinct values only:
SELECT STRING_AGG(DISTINCT product, ', ') FROM orders; -- Postgres / DuckDB
SELECT GROUP_CONCAT(DISTINCT product) FROM orders; -- MySQL / SQLite