В PostgreSQL можно сгруппировать значения в список (или массив) с помощью агрегатной функции array_agg
. Эта функция собирает все значения в группе в один массив.
Пример 1: Группировка значений в список
Предположим, у вас есть таблица orders
:
CREATE TABLE orders (
order_id SERIAL PRIMARY KEY,
customer_id INT,
product_name TEXT
);
INSERT INTO orders (customer_id, product_name) VALUES
(1, 'Laptop'),
(1, 'Mouse'),
(2, 'Keyboard'),
(2, 'Monitor'),
(2, 'Mouse'),
(3, 'Laptop');
Вы хотите сгруппировать все товары (product_name
), заказанные каждым клиентом (customer_id
), в список:
SELECT customer_id, array_agg(product_name) AS products
FROM orders
GROUP BY customer_id;
Результат:
customer_id | products
-------------+-------------------------
1 | {Laptop,Mouse}
2 | {Keyboard,Monitor,Mouse}
3 | {Laptop}
Пример 2: Группировка с уникальными значениями
Если вы хотите, чтобы значения в списке были уникальными, используйте функцию array_agg
вместе с DISTINCT
:
SELECT customer_id, array_agg(DISTINCT product_name) AS unique_products
FROM orders
GROUP BY customer_id;
Результат:
customer_id | unique_products
-------------+-----------------
1 | {Laptop,Mouse}
2 | {Keyboard,Monitor,Mouse}
3 | {Laptop}
Пример 3: Группировка с сортировкой
Если вам нужно отсортировать значения в списке, используйте вложенный запрос с ORDER BY
:
SELECT customer_id, array_agg(product_name ORDER BY product_name) AS sorted_products
FROM orders
GROUP BY customer_id;
Результат:
customer_id | sorted_products
-------------+-------------------------
1 | {Laptop,Mouse}
2 | {Keyboard,Monitor,Mouse}
3 | {Laptop}
Пример 4: Группировка в строку вместо массива
Если вам нужно сгруппировать значения в строку (через разделитель), используйте функцию string_agg
:
SELECT customer_id, string_agg(product_name, ', ') AS product_list
FROM orders
GROUP BY customer_id;
Результат:
customer_id | product_list
-------------+-------------------------
1 | Laptop, Mouse
2 | Keyboard, Monitor, Mouse
3 | Laptop
Пример 5: Группировка с фильтрацией
Вы можете добавить условие WHERE
, чтобы отфильтровать данные перед группировкой:
SELECT customer_id, array_agg(product_name) AS products
FROM orders
WHERE product_name != 'Mouse'
GROUP BY customer_id;
Результат:
customer_id | products
-------------+----------------
1 | {Laptop}
2 | {Keyboard,Monitor}
3 | {Laptop}
Заключение
array_agg
— группирует значения в массив.string_agg
— группирует значения в строку с указанным разделителем.DISTINCT
— убирает дубликаты.ORDER BY
— сортирует значения перед группировкой.
Эти функции очень полезны для агрегации данных в PostgreSQL.
Добавить комментарий