Нужно заполнить отсутствующие периоды времени нулями для каждого идентификатора (Athena SQL) - PullRequest
0 голосов
/ 21 октября 2019

В моих данных я смотрю квартальные подсчеты на пользователя. Для всех недостающих кварталов я хотел бы вменять их в 0. Вот пример:

Вот мой текущий набор данных:

ID Qtr    Count
1  2018Q1 1
1  2018Q3 1
1  2018Q4 2
2  2018Q1 4
2  2018Q2 6
2  2019Q3 2
2  2019Q4 1
3  2018Q1 8
3  2018Q2 5
3  2018Q3 2
3  2018Q4 4
3  2019Q1 5

Обновленная таблица:

ID Qtr    Count
1  2018Q1 1
1  2018Q2 0
1  2018Q3 1
1  2018Q4 2
1  2019Q1 0
1  2019Q2 0
1  2019Q3 0
1  2019Q4 0
2  2018Q1 4
2  2018Q2 6
2  2018Q3 0
2  2018Q4 0
2  2019Q1 0
2  2019Q2 0
2  2019Q3 2
2  2019Q4 1
3  2018Q1 8
3  2018Q2 5
3  2018Q3 2
3  2018Q4 4
3  2019Q1 5
3  2019Q2 0
3  2019Q3 0
3  2019Q4 0

Любая помощь будет высоко ценится.

Ответы [ 3 ]

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

Вы можете создать таблицу, содержащую все ваши кварталы (в примере quarters_), а затем присоединить к ней данные (в примере some_data).

create table some_data (year number, quarter number, data varchar2(10));
insert into some_data values(2018,3,'AAAA');

create table  quarters_ (signature varchar2(20), year number, quarter_number number);
insert into quarters_ (signature, year, quarter_number) values ('2018Q1', 2018, 1);
insert into quarters_ (signature, year, quarter_number) values ('2018Q2', 2018, 2);
insert into quarters_ (signature, year, quarter_number) values ('2018Q3', 2018, 3);
insert into quarters_ (signature, year, quarter_number) values ('2018Q4', 2018, 4);
insert into quarters_ (signature, year, quarter_number) values ('2019Q1', 2019, 1);
insert into quarters_ (signature, year, quarter_number) values ('2019Q2', 2019, 2);
insert into quarters_ (signature, year, quarter_number) values ('2019Q3', 2019, 3);
insert into quarters_ (signature, year, quarter_number) values ('2019Q4', 2019, 4);

select signature as Qtr, count (s.data) as count
from quarters_ q
left join some_data s on s.quarter = q.quarter_number and s.year = q.year
group by q.signature
0 голосов
/ 22 октября 2019

Итак, чтобы решить эту проблему, мы сначала все год + квартал значений для конкретного идентификатора, а затем мы можем рассчитать количество для каждого год + квартал . Таким образом, решение делится на два этапа следующим образом:

  1. Создайте набор данных, чтобы получить все значения года + квартала для идентификатора.
  2. CROSS СОЕДИНИТЕ его с исходными данными, чтобы получить всерезультат.

1. СОЗДАНИЕ БАЗЫ ДАННЫХ:

Чтобы создать набор данных, необходимо выполнить следующие шаги:

  1. Получить уникальный идентификатор, комбинацию года
  2. Преобразовать данные года в данные года + квартала.
  3. Отделить запись массива.

Получить уникальный идентификатор, комбинацию лет:

SELECT ID, ARRAY[substr(Qtr, 1, 4)] AS year from table_name 
GROUP BY ID, ARRAY[substr(Qtr, 1, 4)]

Преобразовать данные года вданные за год и квартал:

WITH dataset AS (
SELECT ID, ARRAY[substr(Qtr, 1, 4)] AS year from table_name 
GROUP BY ID, ARRAY[substr(Qtr, 1, 4)]
)
select ID, transform(year, x->x||'Q1') || transform(year, x->x||'Q2') || transform(year, x->x||'Q3') ||
transform(year, x->x||'Q4') 
AS year from dataset

Отделить его от массива:

WITH dataset AS (
    WITH inner_dataset AS (
      SELECT ID, ARRAY[substr(Qtr, 1, 4)] AS year from table_name 
      GROUP BY ID, ARRAY[substr(Qtr, 1, 4)]
     )
     select ID, transform(year, x->x||'Q1') || transform(year, x->x||'Q2') || 
     transform(year, x->x||'Q3') || transform(year, x->x||'Q4') 
     AS year from inner_dataset
)
SELECT ID,yr from dataset
CROSS JOIN UNNEST(year) AS t(yr)

Результатом этого запроса будет ряд строк ID, год + квартал со всеми четвертями для каждого идентификатора. Теперь следующим шагом будет преобразование его в окончательный набор данных, а затем СОЕДИНЕНИЕ этих данных с исходной таблицей.

2. CROSS СОЕДИНИТЕ его с исходными данными, чтобы получить весь результат.

SELECT table_name.ID,final_dataset.yr,coalesce(table_name.Count,0)
FROM table_name
CROSS JOIN final_dataset
ON table_name.ID = final_dataset.ID AND table_name.Qtr = final_dataset.yr
ORDER BY table_name.ID,final_dataset.yr

coalesce () используется для преобразования значений NULL в 0.

FINAL QUERY:

WITH final_dataset AS (
  WITH dataset AS (
      WITH inner_dataset AS (
        SELECT ID, ARRAY[substr(Qtr, 1, 4)] AS year from table_name 
        GROUP BY ID, ARRAY[substr(Qtr, 1, 4)]
       )
       select ID, transform(year, x->x||'Q1') || transform(year, x->x||'Q2') || 
       transform(year, x->x||'Q3') || transform(year, x->x||'Q4') 
       AS year from inner_dataset
  )
  SELECT ID,yr from dataset
  CROSS JOIN UNNEST(year) AS t(yr)
)
SELECT table_name.ID,final_dataset.yr,coalesce(table_name.Count,0)
FROM table_name
CROSS JOIN final_dataset
ON table_name.ID = final_dataset.ID AND table_name.Qtr = final_dataset.yr
ORDER BY table_name.ID,final_dataset.yr

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

Вам нужно составить таблицу с нулями. Для этого особенно пригодятся sequence() и UNNEST.

Вот пример, где ваши данные имеют только четверть и число (нет id).

presto:default> SELECT coalesce(t.q, a.q), coalesce(t.c, 0)
             -> FROM (VALUES ('2018Q1', 1)) t(q, c)
             -> RIGHT OUTER JOIN (
             ->     SELECT CAST(y AS varchar) || 'Q' || CAST(x AS varchar) AS q
             ->     FROM UNNEST(sequence(2018, 2019)) _(y)
             ->     CROSS JOIN UNNEST(sequence(1, 4)) _(x)
             -> ) a ON t.q = a.q
             -> ;
 _col0  | _col1
--------+-------
 2018Q1 |     1
 2018Q3 |     0
 2019Q1 |     0
 2018Q4 |     0
 2019Q3 |     0
 2019Q2 |     0
 2018Q2 |     0
 2019Q4 |     0
(8 rows)

(протестировано в Presto 322)

Вы можете легко обобщить его для id:

presto:default> WITH source_table AS (
             ->     SELECT *
             ->     FROM (VALUES (1, '2018Q1', 13), (2, '2018Q2', 42)) t(id, q, c)
             -> )
             -> SELECT id, q, coalesce(c, 0)
             -> FROM source_table
             -> RIGHT OUTER JOIN (
             ->     SELECT id, CAST(y AS varchar) || 'Q' || CAST(x AS varchar) AS q
             ->     FROM (SELECT DISTINCT id FROM source_table)
             ->     CROSS JOIN UNNEST(sequence(2018, 2019)) _(y)
             ->     CROSS JOIN UNNEST(sequence(1, 4)) _(x)
             -> ) a USING(id, q)
             -> ;
 id |   q    | _col2
----+--------+-------
  1 | 2018Q1 |    13
  2 | 2018Q2 |    42
  2 | 2019Q3 |     0
  1 | 2018Q2 |     0
  1 | 2019Q3 |     0
  2 | 2018Q4 |     0
  1 | 2019Q2 |     0
  1 | 2019Q4 |     0
  2 | 2019Q4 |     0
  2 | 2018Q3 |     0
  2 | 2019Q2 |     0
  1 | 2018Q3 |     0
  1 | 2019Q1 |     0
  2 | 2019Q1 |     0
  2 | 2018Q1 |     0
  1 | 2018Q4 |     0
(16 rows)
...