Redshift, подсчет элементов в столбце, разделенных запятой - PullRequest
0 голосов
/ 08 октября 2019

У меня есть данные, что в столбце сохранена группа чисел

|  user   |      col                     |
| ------- |         -------              |
| 1       | 3,7,11,25,44,56,77,32,34,55  |
| 2       | 3,7,25,44,37,89,56,99,103,13 |
| 1       | 3,10,11,25,44,56,33,32,34,55  |

Я знаю, что могу разделить столбцы и подсчитать, но есть ли у нас другой способ подсчета чисел?

|user| new-col | count|
| -------      | ------- | 
| 1   | 3      | 2 |
| 1   | 7      | 1 |
| 1   | 11     | 2 |
| 1   | 25     | 2 |
| 1   | 44     |2  |
| 1   | 56     |1  |
| 1   | 77     | 1 |
| 1   | 32     | 2 |

Ответы [ 4 ]

0 голосов
/ 08 октября 2019

Подсчитайте количество запятых в строке, используя REGEXP_COUNT и добавьте 1.

CREATE TEMP TABLE examples (
      user_id INT
    , value_list VARCHAR 
);
INSERT INTO examples
          SELECT 1 , '3,7,11,25,44,56,77,32,34,55' 
UNION ALL SELECT 2 , '3,7,25,44,37,89,56,99,103,13'
UNION ALL SELECT 1 , '3,10,11,25,44,56,33,32,34,55'
;
SELECT user_id
     , SUM(REGEXP_COUNT(value_list,',')+1) value_count 
FROM examples
GROUP BY 1
;

Вывод

 user_id | value_count
---------+-------------
       1 |          20
       2 |          10
0 голосов
/ 08 октября 2019

Вы можете использовать запрос объединения вместе с SPLIT_PART:

WITH cte AS (
    SELECT user, SPLIT_PART(col, ',', 1) AS val FROM yourTable UNION ALL
    SELECT user, SPLIT_PART(col, ',', 2) FROM yourTable UNION ALL
    SELECT user, SPLIT_PART(col, ',', 3) FROM yourTable UNION ALL
    SELECT user, SPLIT_PART(col, ',', 4) FROM yourTable UNION ALL
    SELECT user, SPLIT_PART(col, ',', 5) FROM yourTable UNION ALL
    SELECT user, SPLIT_PART(col, ',', 6) FROM yourTable UNION ALL
    SELECT user, SPLIT_PART(col, ',', 7) FROM yourTable UNION ALL
    SELECT user, SPLIT_PART(col, ',', 8) FROM yourTable UNION ALL
    SELECT user, SPLIT_PART(col, ',', 9) FROM yourTable UNION ALL
    SELECT user, SPLIT_PART(col, ',', 10) FROM yourTable
)

SELECT
    user,
    val,
    COUNT(*) AS cnt
FROM cte
GROUP BY
    user,
    val;

Но учтите, что все, что мы делаем выше в CTE, на самом деле просто нормализует ваши данные, так что каждое отношение пользователя и значения занимаетотдельная запись. В идеале вам следует изменить дизайн таблицы и отойти от хранения CSV.

Если вместо этого вам нужно просто подсчитать число на пользователя, используйте:

SELECT
    user,
    COUNT(*) AS cnt
FROM cte
GROUP BY
    user;
0 голосов
/ 08 октября 2019

Запрос.

with t as (
select 1 as user, '3,7,11,25,44,56,77,32,34,55' as col 
union all
select 2 as user, '3,7,25,44,37,89,56,99,103,13' as col
union all
select 1 as user, '3,10,11,25,44,56,33,32,34,55' as col
)
select a.user, a.val, count(*) as cnt
from (
    select a.user
      , SPLIT_PART(a.col, ',', b.no) as val
    from t a
    cross join (
      select * from generate_series(1,10) as no
    ) b
) a
group by a.user, a.val
order by a.user, a.val
0 голосов
/ 08 октября 2019

Это отвечает первоначальной версии вопроса.

Вы можете посчитать количество значений, разделенных запятыми, с помощью:

select (case when col = '' then 0
             else length(col) - length(replace(col, ',', '')) + 1
        end) as values_count       
from t;

При этом вам следует исправить свою модель данных, чтобы выне хранят несколько значений в столбце. Особенно утомительно, что вы также храните числа в виде строк. Вы хотите соединительную / ассоциативную таблицу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...