Получите пропущенные месяцы от даты для каждого идентификатора - PullRequest
0 голосов
/ 05 января 2019

У меня есть таблица, которая содержит, memberid и дату. Я хочу, чтобы каждый участник отображал пропущенные месяцы с даты.

Вот таблица ввода и ожидаемая таблица.

enter image description here

Я попытался создать временную таблицу для генерации рядов от минимального до максимального месяца, но мне не удается объединить эти две таблицы. Может ли кто-нибудь помочь мне в этом.

Вот код, который я уже пробовал.

Извлечение дат и сохранение их в новом столбце

create temp table temp_table as select *, date_part('month', premiumpadidate) from training.premium  distributed by(memberid);

Создать серию

create temp table temp_table_series as 
(select * from generate_series(cast((select min(date_part) from temp_table group by (memberid)) as integer), cast((select max(date_part) from temp_table group by (memberid)) as integer) )
) 
distributed by (generate_series)

Я не понимаю, как объединить две таблицы, чтобы получить месяцы, пропущенные каждым сотрудником.

Пожалуйста, помогите мне в этом

1 Ответ

0 голосов
/ 10 января 2019

Это легко сделать с помощью функции, но вы можете выполнить ее одним щелчком мыши. Вот что я сделал, чтобы помочь тебе. Я смоделировал ваши данные с помощью объединения и добавил члена "102":

select 101 as id, '2016-01-01'::date as paidDate union
select 101 as id, '2016-02-01'::date as paidDate union
select 101 as id, '2016-04-01'::date as paidDate union
select 101 as id, '2016-08-01'::date as paidDate union
select 101 as id, '2016-11-01'::date as paidDate union
select 102 as id, '2016-01-01'::date as paidDate union
select 102 as id, '2016-02-01'::date as paidDate union
select 102 as id, '2016-04-01'::date as paidDate union
select 102 as id, '2016-08-01'::date as paidDate union
select 102 as id, '2016-11-01'::date as paidDate

Вы должны выглядеть как таблица.

Затем с вашей таблицей я сделал 12 «дел», чтобы проверить месяц. Я поставил значение «0», если месяц найден, и значение месяца, если нет, например:

select t.id, extract(month from t.paidDate),
    case when extract(month from t.paidDate) = 1 then 0 else 1 end as m1,
    case when extract(month from t.paidDate) = 2 then 0 else 2 end as m2,
    case when extract(month from t.paidDate) = 3 then 0 else 3 end as m3,
    case when extract(month from t.paidDate) = 4 then 0 else 4 end as m4,
    case when extract(month from t.paidDate) = 5 then 0 else 5 end as m5,
    case when extract(month from t.paidDate) = 6 then 0 else 6 end as m6,
    case when extract(month from t.paidDate) = 7 then 0 else 7 end as m7,
    case when extract(month from t.paidDate) = 8 then 0 else 8 end as m8,
    case when extract(month from t.paidDate) = 9 then 0 else 9 end as m9,
    case when extract(month from t.paidDate) = 10 then 0 else 10 end as m10,
    case when extract(month from t.paidDate) = 11 then 0 else 11 end as m11,
    case when extract(month from t.paidDate) = 12 then 0 else 12 end as m12
from (
    select 101 as id, '2016-01-01'::date as paidDate union
    select 101 as id, '2016-02-01'::date as paidDate union
    select 101 as id, '2016-04-01'::date as paidDate union
    select 101 as id, '2016-08-01'::date as paidDate union
    select 101 as id, '2016-11-01'::date as paidDate union
    select 102 as id, '2016-01-01'::date as paidDate union
    select 102 as id, '2016-02-01'::date as paidDate union
    select 102 as id, '2016-04-01'::date as paidDate union
    select 102 as id, '2016-08-01'::date as paidDate union
    select 102 as id, '2016-11-01'::date as paidDate
) t

После этого нам нужно отбросить месяцы, которые существуют в данных. Я сделал это, используя группу по идентификатору, получая МИНУТНЫЙ месяц. Это отбросит месяцы, которые существуют (потому что мы обнулили их в этом случае), и сохранит месяцы, которые не существуют. Как это:

select id, 
    min(m1) as m1, min(m2) as m2, min(m3) as m3, min(m4) as m4, min(m5) as m5, min(m6) as m6, 
    min(m7) as m7, min(m8) as m8, min(m9) as m9, min(m10) as m10, min(m11) as m11, min(m12) as m12
from 
(
    select t.id, extract(month from t.paidDate),
        case when extract(month from t.paidDate) = 1 then 0 else 1 end as m1,
        case when extract(month from t.paidDate) = 2 then 0 else 2 end as m2,
        case when extract(month from t.paidDate) = 3 then 0 else 3 end as m3,
        case when extract(month from t.paidDate) = 4 then 0 else 4 end as m4,
        case when extract(month from t.paidDate) = 5 then 0 else 5 end as m5,
        case when extract(month from t.paidDate) = 6 then 0 else 6 end as m6,
        case when extract(month from t.paidDate) = 7 then 0 else 7 end as m7,
        case when extract(month from t.paidDate) = 8 then 0 else 8 end as m8,
        case when extract(month from t.paidDate) = 9 then 0 else 9 end as m9,
        case when extract(month from t.paidDate) = 10 then 0 else 10 end as m10,
        case when extract(month from t.paidDate) = 11 then 0 else 11 end as m11,
        case when extract(month from t.paidDate) = 12 then 0 else 12 end as m12
    from 
    (
        select 101 as id, '2016-01-01'::date as paidDate union
        select 101 as id, '2016-02-01'::date as paidDate union
        select 101 as id, '2016-04-01'::date as paidDate union
        select 101 as id, '2016-08-01'::date as paidDate union
        select 101 as id, '2016-11-01'::date as paidDate union
        select 102 as id, '2016-01-01'::date as paidDate union
        select 102 as id, '2016-02-01'::date as paidDate union
        select 102 as id, '2016-04-01'::date as paidDate union
        select 102 as id, '2016-08-01'::date as paidDate union
        select 102 as id, '2016-11-01'::date as paidDate
    ) t
) t
group by t.id

Вы можете использовать его в качестве своего результата, чтобы выполнять все ваши правила, но давайте очистим его немного больше, удалив нули, например:

select id,
    case when m1 = 0 then null else m1 end, case when m2 = 0 then null else m2 end,
    case when m3 = 0 then null else m3 end, case when m4 = 0 then null else m4 end,
    case when m5 = 0 then null else m5 end, case when m6 = 0 then null else m6 end,
    case when m7 = 0 then null else m7 end, case when m8 = 0 then null else m8 end,
    case when m9 = 0 then null else m9 end, case when m10 = 0 then null else m10 end,
    case when m11 = 0 then null else m11 end, case when m12 = 0 then null else m12 end
from 
(
    select id, 
        min(m1) as m1, min(m2) as m2, min(m3) as m3, min(m4) as m4, min(m5) as m5, min(m6) as m6, 
        min(m7) as m7, min(m8) as m8, min(m9) as m9, min(m10) as m10, min(m11) as m11, min(m12) as m12
    from 
    (
        select t.id, extract(month from t.paidDate),
            case when extract(month from t.paidDate) = 1 then 0 else 1 end as m1,
            case when extract(month from t.paidDate) = 2 then 0 else 2 end as m2,
            case when extract(month from t.paidDate) = 3 then 0 else 3 end as m3,
            case when extract(month from t.paidDate) = 4 then 0 else 4 end as m4,
            case when extract(month from t.paidDate) = 5 then 0 else 5 end as m5,
            case when extract(month from t.paidDate) = 6 then 0 else 6 end as m6,
            case when extract(month from t.paidDate) = 7 then 0 else 7 end as m7,
            case when extract(month from t.paidDate) = 8 then 0 else 8 end as m8,
            case when extract(month from t.paidDate) = 9 then 0 else 9 end as m9,
            case when extract(month from t.paidDate) = 10 then 0 else 10 end as m10,
            case when extract(month from t.paidDate) = 11 then 0 else 11 end as m11,
            case when extract(month from t.paidDate) = 12 then 0 else 12 end as m12
        from 
        (
            select 101 as id, '2016-01-01'::date as paidDate union
            select 101 as id, '2016-02-01'::date as paidDate union
            select 101 as id, '2016-04-01'::date as paidDate union
            select 101 as id, '2016-08-01'::date as paidDate union
            select 101 as id, '2016-11-01'::date as paidDate union
            select 102 as id, '2016-01-01'::date as paidDate union
            select 102 as id, '2016-02-01'::date as paidDate union
            select 102 as id, '2016-04-01'::date as paidDate union
            select 102 as id, '2016-08-01'::date as paidDate union
            select 102 as id, '2016-11-01'::date as paidDate
        ) t
    ) t
    group by 
    t.id
) t

Вот и все, надеюсь, что это немного поможет.

Привет

...