选择具有滚动日期条件的数据

时间:2016-10-31 17:18:38

标签: sql postgresql

以下查询会返回给定月份和品牌的“成员”的明确计数(参见下图)。

select to_char(transaction_date, 'YYYY-MM') as month, brand,
   count(distinct UNIQUE_MEM_ID) as distinct_count
from source.table
group by  to_char(transaction_date, 'YYYY-MM'), brand;

收集的数据在月份结束后的15天滞后(意味着2016年9月的月度数据在10月15日之前不会是100%)。我只关心月度数据。

我想建立的查询:直到本月15日(10月),上个月的数据(9月)应反映8月份的数据。当前的部分月份(10月)应该默认为上个月,因此也是上述逻辑。

本月15日之后,上个月的数据(9月)现在是100%,因此9月应反映9月(10月将反映9月至11月15日,依此类推)。

当前的部分月份将始终=前一个月。查询的复杂性是如何在上个月计算。

此查询将以滚动方式运行,因此需要是动态的。

要明确的是,我正在尝试构建一个查询,其中上个月的distinct_count(直到当月月末+15天)应该反映(当前月份 - 2)值(对于每个相应的品牌)。在该月结束后的15天,前一个月=(当前月 - 1)。

部分当前月份默认为上个月的数据。 15天的值应该是可变的/可修改的。

enter image description here

4 个答案:

答案 0 :(得分:1)

首先,将查询简化为:

select to_char(transaction_date, 'YYYY-MM') as month, brand,
       count(distinct members) as distinct_count 
from source.table
group by members, to_char(transaction_date, 'YYYY-MM'), brand;

然后,你会遇到问题。问题是一行(比如从8月20日开始)需要分为两组。一个简单的group by将无法解决此问题。所以,让我们使用union all。我认为结果是这样的:

select date_trunc('month', transaction_date) as month, brand,
       count(distinct members) as distinct_count 
from source.table
where (date_trunc('month', transaction_date) < date_trunc('month' current_date) - interval '1 month') or
      (day(current_date) > 15 and date_trunc('month', transaction_date) = date_trunc('month' current_date) - interval '1 month')
group by date_trunc('month', transaction_date), brand
union all
select date_trunc('month' current_date) - interval '1 month' as month, brand,
       count(distinct members) as distinct_count 
from source.table
where (day(current_date) < 15 and date_trunc('month', transaction_date) = date_trunc('month' current_date) - interval '1 month')
group by brand;

答案 1 :(得分:0)

由于您已经有了工作查询,因此我专注于子选择。您可以在CASE使用的条件是https://jsfiddle.net/fr6b4b2d/,尤其是&#34;搜索案例&#34;

case
when extract(day from current_date) < 15 then
    extract(month from current_date - interval '2 months')
else
    extract(month from current_date - interval '1 month')
end case

例如,这可以用作where子句的一部分。

答案 2 :(得分:0)

以下是一些sudo代码,用于获取间隔的开始日期和结束日期。

开始日期:

ControllerThree

这将仅在第15天之后返回当月,从那里你可以减去整整一个月来获得你的起点。

结束日期: 要计算这一点,请抓住开始日期,再加上一个月,减去一天。

答案 3 :(得分:0)

如果源表由transaction_date分区,则此语法(不使用表达式屏蔽transaction_date)启用分区取消。

select      to_char(transaction_date, 'YYYY-MM')    as month
           ,count (distinct members)                as distinct_count
           ,brand                                   as brand

FROM        source.table

where       transaction_date    between date_trunc('month', current_date) - case when extract (day from current_date) >= 15 then 1 else 2 end * interval '1' month
                                and     date_trunc('month', current_date) - case when extract (day from current_date) >= 15 then 0 else 1 end * interval '1' month - interval '1' day

group by    to_char(transaction_date, 'YYYY-MM')
           ,brand
;