Есть ли способ в SQL агрегировать столбец по строкам и потенциально дублировать строки на основе другого значения поля в Redshift? - PullRequest
1 голос
/ 11 апреля 2020

Итак, у меня есть таблица, давайте назовем ее shipment_items, которая перечисляет по shipment_id отдельные элементы, содержащиеся в отправлении, и их количество.

+-------------+-------------+----------+
| shipment_id |  item_name  | quantity |
+-------------+-------------+----------+
|           1 | cleanser    |        1 |
|           1 | moisturizer |        2 |
|           2 | cleanser    |        2 |
|           2 | body wash   |        1 |
|           3 | cleanser    |        1 |
|           3 | moisturizer |        2 |
|           4 | cleanser    |        1 |
|           4 | moisturizer |        1 |
+-------------+-------------+----------+

Я хочу вернуть таблицу, которая выглядит следующим образом

+------------------------------------+----------+
|               items                | num_ship |
+------------------------------------+----------+
| cleanser, moisturizer, moisturizer |        2 |
| body wash, cleanser, cleanser      |        1 |
| cleanser, moisturizer              |        1 |
+------------------------------------+----------+

Есть ли способ в sql сделать это? Я думаю кое-что с list_agg, но сложная часть дублирует item_names на основе поля количества. В новой таблице я пытаюсь показать, что было 2 партии, которые содержали 2 увлажнителя и 1 моющее средство, и 1 партия, содержащая 2 моющих средства и 1 корпус ва sh.

** EDIT ** Решено благодаря @Gordon Linoff

Новая результирующая таблица будет выглядеть следующим образом

+------------------------------------+----------+
|               items                | num_ship |
+------------------------------------+----------+
| cleanser: 1, moisturizer: 2        |        2 |
| body wash: 1, cleanser: 2          |        1 |
| cleanser: 1, moisturizer: 1        |        1 |

1 Ответ

2 голосов
/ 11 апреля 2020

Вы можете использовать listagg():

select listagg(item_name, ', ') within group (order by item_name) as items,
       quantity
from t
group by quantity
order by quantity desc;

РЕДАКТИРОВАТЬ:

Я думаю, вы хотите два уровня агрегации:

select items, count(*)
from (select shipment_id,
             listagg(distinct item_name, ', ') within group (order by item_name) as items
      from t
      group by shipment_id
     ) s
group by items
order by count(*) desc;

Это не включает дубликаты в списке позиций.

РЕДАКТИРОВАТЬ II:

Для точных совпадений укажите количество:

select items, count(*)
from (select shipment_id,
             listagg(distinct item_name || ':' || quantity, ', ') within group (order by item_name) as items
      from t
      group by shipment_id
     ) s
group by items
order by count(*) desc;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...