如何计算连续日期系列中的一天数?

时间:2018-06-15 08:59:42

标签: sql postgresql gaps-and-islands

我有一张桌子

id name     created_at
1  name 1   08/01/2017
2  name 2   08/02/2017
3  name 3   08/03/2017
4  name 4   08/05/2017
5  name 5   08/06/2017
6  name 6   08/07/2017
7  name 7   08/10/2017
8  name 8   08/12/2017

我需要添加一个列,其中所有行都是排名,但是如果它们是每天创建的。

结果应如下所示

id name     created_at   days_on
1  name 1   08/01/2017   1
2  name 2   08/02/2017   2
3  name 3   08/03/2017   3
4  name 4   08/05/2017   1
5  name 5   08/06/2017   2
6  name 6   08/07/2017   3
7  name 7   08/10/2017   null
8  name 8   08/12/2017   null

2 个答案:

答案 0 :(得分:1)

many answers描述了解决类似问题的典型方法,您还可以在其中找到下面使用的技术的解释。

select 
    id, name, created_at, 
    case when count(*) over wa > 1 then row_number() over wo end as rank
from (
    select 
        id, name, created_at, 
        sum(first) over w as part
    from (
        select *, (lag(created_at) over w+ 1 is distinct from created_at)::int as first
        from my_table
        window w as (order by id)
        ) s
    window w as (order by id)
    ) s
window 
    wa as (partition by part),
    wo as (partition by part order by id);

DbFiddle.

答案 1 :(得分:0)

这是群岛问题的变体。让我展示一个使用lag()来定义组的解决方案:

  • lag()前一天
  • 获得群组的累积金额
  • row_number()分配最终值

这适用于:

select id, name, created_at,
       (case when count(*) over (partition by grp) > 1
             then row_number() over (partition by grp order by id)
        end) as days_on
from (select t.*,
             sum( (prev_ca <> created_at - interval '1 day')::int ) as grp
      from (select t.*,
                   lag(created_at) over (order by id) as prev_ca
            from t
     ) t;