简体   繁体   English

用窗口函数分组? Postgres的

[英]grouping with window functions? postgres

i have a short question 我有一个简短的问题

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

it should give me at the end a resultset where i have an additional column which is a unique number per "group" the group start from 1/0 and goes till the last 0 entry for the same name 它应该给我一个结果集,其中我有一个额外的列,这是一个唯一的数字,每个“组”组从1/0开始,直到同一个名字的最后0个条目

result 结果

enter image description here 在此输入图像描述

can I achieve this with a window function ? 我可以通过窗口功能来实现吗? i tried with different dense_rank and row_number with preceeing etc but nothing worked thanks 我尝试了不同的dense_rank和row_number与先前等,但没有任何工作谢谢

You don't specify what ordering is happening between "start" and "last", but that's okay for row_number() . 您没有指定“开始”和“最后”之间发生了什么排序,但这对row_number() If needed, you can add that to the first line of the following solution. 如果需要,您可以将其添加到以下解决方案的第一行。

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)

If there's a primary key in data_set , you can return it from t3 to use in the final join instead. 如果data_set有主键, data_set可以从t3返回它以在最终连接中使用。 That is, 那是,

with ...
     t2 as (select row_number ...),
     t3 as (select id, ...)
select data_set.*, dense_rank() ... join t3 using (id)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM