如何跟踪每周的增长情况,同时计算出缺少的几周

时间:2019-01-10 16:37:47

标签: sql postgresql

假设我们有一个match表,该表的简化版本看起来像这样:

Column                             |           Type           | Collation | Nullable |      Default
-----------------------------------+--------------------------+-----------+----------+--------------------
uuid                               | uuid                     |           | not null | uuid_generate_v4()
present_state                      | text                     |           |          |
created_at                         | timestamp with time zone |           | not null |
updated_at                         | timestamp with time zone |           |          |

我正在尝试从过去某个任意日期开始,以一周为一周的方式显示当前比赛的数量。

基于该架构,我们可以通过查看created_at列并对其进行分组和计数,来了解一周中有多少次新的有效匹配。对于完成的比赛,我们可以通过查看updated_at列并确保present_state已完成来做类似的事情。

还要考虑的另一件事是,可能有几周根本没有比赛发生,比赛可以无限期进行。我一直在试图迫使一些CTE提供一个表,其中包含比赛开始的每个日期的条目,一个执行相反操作并具有每个比赛结束时间的日期的表以及我可以加入的生成的时间序列考虑到缺少的几周。这是到目前为止我得到的:

    ; WITH matches_begun AS 
        (
            SELECT 
                date_trunc('day', created_at)::date AS date 
            FROM matches
        )
    , matches_finished AS 
        (
            SELECT 
                 date_trunc('day', updated_at)::date AS date 
            FROM matches 
            WHERE present_state = 'finished'
        )
    , weekly_time_series AS 
        (
            select  generate_series( '2018-01-01', current_date, interval '1 day' )
        )

我不能全神贯注于如何返回数据,该数据将显示从过去某个时间点到本周内每周有多少次有效比赛。

1 个答案:

答案 0 :(得分:1)

这可能是您想要的。

with weekly_time_series(report_date) AS (
  select  generate_series( '2018-01-01', current_date, interval '1 day' )
), weekly_counts(report_week, weekly_count) as (
  select date_trunc('week', report_date) 
       , count(distinct uuid) 
    from weekly_time_series
    left join matches
      on date_trunc('day', created_at) <= report_date
     and (present_state <> 'finished' or 
      report_date < date_trunc('day', updated_at))
   group by date_trunc('week', report_date)
)
select report_week
     , weekly_count
     , weekly_count - coalesce(lag(weekly_count) over (order by report_week), 0) delta
  from weekly_counts;