Redshift создает все комбинации любой длины для значений в одном столбце - PullRequest
0 голосов
/ 18 мая 2018

Как мы можем создать все комбинации любой длины для значений в одном столбце и вернуть различный счетчик другого столбца для этой комбинации?

Таблица:

+------+--------+
| Type |  Name  |
+------+--------+
| A    | Tom    |
| A    | Ben    |
| B    | Ben    |
| B    | Justin |
| C    | Ben    |
+------+--------+

Таблица вывода:

+-------------+-------+
| Combination | Count |
+-------------+-------+
| A           |     2 |
| B           |     2 |
| C           |     1 |
| AB          |     3 |
| BC          |     2 |
| AC          |     2 |
| ABC         |     3 |
+-------------+-------+

Когда комбинация только A, есть Том и Бен, поэтому это 2.

Когда комбинация только B, 2 разных имени, поэтому это 2.

Когда комбинация A и B, 3 разных имени: Том, Бен, Джастин, поэтому 3.

Я работаю в Amazon Redshift.Спасибо!

Ответы [ 2 ]

0 голосов
/ 19 мая 2018

Невозможно сгенерировать все возможные комбинации (A, B, C, AB, AC, BC и т. Д.) В Amazon Redshift.

(ну, вы можете выбрать каждое уникальное значение, добавив их водну строку, отправьте ее в пользовательскую функцию, извлеките результат в несколько строк, а затем соедините его с большим запросом, но на самом деле это не то, что вы хотели бы попробовать.)

Один подход создаст таблицу, содержащую все возможные комбинации - вам нужно написать небольшую программу для этого (например, используя itertools в Python).Затем вы можете объединить данные с этим достаточно легко получить желаемый результат (например, IF 'ABC' CONTAINS '%A%').

0 голосов
/ 18 мая 2018

ПРИМЕЧАНИЕ. Отвечает на исходную версию вопроса с тегом Postgres.

Вы можете сгенерировать все комбинации с помощью этого кода

with recursive td as (
      select distinct type
      from t
     ),
     cte as (
      select td.type, td.type as lasttype, 1 as len
      from td
      union all
      select cte.type || t.type, t.type as lasttype, cte.len + 1
      from cte join
           t
           on 1=1 and t.type > cte.lasttype
     )

Затем вы можете использовать его в join:

with recursive t as (
      select *
      from (values ('a'), ('b'), ('c'), ('d')) v(c)
     ),
     cte as (
      select t.c, t.c as lastc, 1 as len
      from t
      union all
      select cte.type || t.type, t.type as lasttype, cte.len + 1
      from cte join
           t
           on 1=1 and t.type > cte.lasttype
     )
select type, count(*)
from (select name, cte.type, count(*)
      from cte join
           t
           on cte.type like '%' || t.type || '%'
      group by name, cte.type
      having count(*) = length(cte.type)
     ) x
group by type
order by type;
...