группировка с оконными функциями? Postgres - PullRequest
0 голосов
/ 21 марта 2019

у меня короткий вопрос

select 
*
 from 
(
select 1 do_switch, 'abc', '2001-01-01'::TIMESTAMP 
union all
select 0 do_switch, 'xyz', '2001-01-01'::TIMESTAMP 
union all
select 1 do_switch, 'xyz', '2001-02-01'::TIMESTAMP 
union all
select 0 do_switch, 'bcd', '2001-01-01'::TIMESTAMP 
union all
select 0 do_switch, 'bcd', '2001-02-01'::TIMESTAMP 
union all
select 0 do_switch, 'bcd', '2001-03-01'::TIMESTAMP 
union all
select 0 do_switch, 'bcd', '2001-04-01'::TIMESTAMP 
union all
select 0 do_switch, 'bcd', '2001-05-01'::TIMESTAMP 
union all
select 0 do_switch, 'bcd', '2001-06-01'::TIMESTAMP 
union all
select 0 do_switch, 'bcd', '2001-07-01'::TIMESTAMP 
union all
select 1 do_switch, 'bcd', '2001-08-01'::TIMESTAMP 
union all
select 0 do_switch, 'bcd', '2001-09-01'::TIMESTAMP 
union all
select 0 do_switch, 'bcd', '2001-10-01'::TIMESTAMP 
union all
select 0 do_switch, 'bcd', '2001-11-01'::TIMESTAMP 
union all
select 1 do_switch, 'bcd', '2001-12-01'::TIMESTAMP 
) data_set

в конце он должен дать мне набор результатов, где у меня есть дополнительный столбец, который является уникальным числом для каждой "группы", начиная с 1/0 и заканчиваядо последней 0 записи для того же имени

результат

введите описание изображения здесь

Могу ли я добиться этого с помощьюоконная функция?я пробовал с другим плотным_ранком и row_number с предшествующим и т. д., но ничего не помогло, спасибо

1 Ответ

0 голосов
/ 22 марта 2019

Вы не указываете, какой порядок происходит между «началом» и «последним», но это нормально для row_number().При необходимости вы можете добавить это в первую строку следующего решения.

with t1 as (select *, row_number() over (/*define order here*/) from data_set),
     t2 as (select row_number from t1 where do_switch = 1),
     t3 as (select row_number,
                   (
                     select min(t2.row_number)
                       from t2
                      where t2.row_number >= t1.row_number
                   )
              from t1
           )
 select t1.*, dense_rank() over (order by min) from t1 join t3 using (row_number);
 do_switch |   name   |      timestamp      | row_number | dense_rank 
-----------+----------+---------------------+------------+------------
         1 | abc      | 2001-01-01 00:00:00 |          1 |          1
         0 | xyz      | 2001-01-01 00:00:00 |          2 |          2
         1 | xyz      | 2001-02-01 00:00:00 |          3 |          2
         0 | bcd      | 2001-01-01 00:00:00 |          4 |          3
         0 | bcd      | 2001-02-01 00:00:00 |          5 |          3
         0 | bcd      | 2001-03-01 00:00:00 |          6 |          3
         0 | bcd      | 2001-04-01 00:00:00 |          7 |          3
         0 | bcd      | 2001-05-01 00:00:00 |          8 |          3
         0 | bcd      | 2001-06-01 00:00:00 |          9 |          3
         0 | bcd      | 2001-07-01 00:00:00 |         10 |          3
         1 | bcd      | 2001-08-01 00:00:00 |         11 |          3
         0 | bcd      | 2001-09-01 00:00:00 |         12 |          4
         0 | bcd      | 2001-10-01 00:00:00 |         13 |          4
         0 | bcd      | 2001-11-01 00:00:00 |         14 |          4
         1 | bcd      | 2001-12-01 00:00:00 |         15 |          4
(15 rows)

Если в data_set есть первичный ключ, вы можете вернуть его из t3 для использования вокончательное присоединение вместо.То есть

with ...
     t2 as (select row_number ...),
     t3 as (select id, ...)
select data_set.*, dense_rank() ... join t3 using (id)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...