带frame子句和where子句的SQL sum窗口函数

带frame子句和where子句的SQL sum窗口函数,sql,window-functions,presto,Sql,Window Functions,Presto,我的表格结构如下: month | ds | item | qty| -------------------------- 1/1/20 | 2020-02-01 | abc | 0 | 2/1/20 | 2020-03-01 | abc | 0 | 3/1/20 | 2020-04-01 | abc | 0 | 4/1/20 | 2020-05-01 | abc | 0 | 5/1/20 | 2020-06-01 | abc | 0 |

我的表格结构如下:

month  | ds         | item | qty|
--------------------------
1/1/20 | 2020-02-01 | abc | 0 |    
2/1/20 | 2020-03-01 | abc | 0 |     
3/1/20 | 2020-04-01 | abc | 0 |     
4/1/20 | 2020-05-01 | abc | 0 |     
5/1/20 | 2020-06-01 | abc | 0 |     
6/1/20 | 2020-07-01 | abc | 50 |    
7/1/20 | 2020-08-01 | abc | 50 |    
8/1/20 | 2020-08-09 | abc | 50 |    
9/1/20 | 2020-08-09 | abc | 50 |
month  | ds         | item | qty| 90d_sum
--------------------------
1/1/20 | 2020-02-01 | abc | 0 | 0    
2/1/20 | 2020-03-01 | abc | 0 | 0     
3/1/20 | 2020-04-01 | abc | 0 | 90
该表由ds(datestamp)列进行分区。每个分区有几个月,从2019年到2021年

我需要能够计算90天、180天和365天期间的数量总和,但条件如下:如果月份小于今天的日期,则我们需要使用从下个月第一个月开始的ds(即,如果我们要计算7月的数量,则我们将使用8月1日的ds-如表所示)。如果月份是当前月份或未来月份,则我需要使用可用的最新ds

我曾尝试使用窗口函数进行求和,但当涉及多个分区时,这不起作用。b/c我需要使用同一个分区进行求和。例如,1/1/20我需要使用2020-02-01分区计算2月、3月、4月的总和(如果您在表2/1/20到4/1/20中看到,每行使用一个diff分区)。换句话说,我需要这样的东西:

select SUM(qty) OVER (
        PARTITION BY
            item
        ORDER BY
            DATE(month) ROWS BETWEEN 1 FOLLOWING AND 3 FOLLOWING
    ) AS sum_90_qty
 from table A
 where ds = <whatever is in the ds column> 
这是假设(2020-02-01分区中的2/1/20、3/1/20、4/1/20都是0)。2020-03-01年的3/1/20、4/1/20、5/1/20分区情况也是如此。2020-04-01分区的示例:4/1/20有0,5/1/20有40,6/1/20有50-->所以0+40+50的和=90。 注意:我所包含的数字只是随机的,但其想法是需要根据月值和ds列求和3个月


谢谢

您希望为每个月计算适当的
ds
。这将是该月或最近一个月之后的第一个月。因此,对于每个
项目
/
月份
组合,我们可以计算:

select a.*
from (select a.*,
             row_number() over (partition by item, month
                                order by (ds > month) desc,
                                         (case when ds > month then ds end) asc,
                                         ds desc
                               ) as seqnum
      from a
     ) a
where seqnum = 1;
然后可以将此逻辑合并到最终查询中。我想那只是:

select a.*,
       sum(qty) over (partition by item 
                      order by date(month)
                      rows between 1 following and 3 following
                     ) as running_qty_3month
from (select a.*,
             row_number() over (partition by item, month
                                order by (ds > month) desc,
                                         (case when ds > month then ds end) asc,
                                         ds desc
                               ) as seqnum
      from a
     ) a
where seqnum = 1;

请添加您的预期输出table@sammywemmy谢谢,我已经添加了预期结果。谢谢@Gordon,很抱歉,我忘了提到我已经计算了需要使用的正确ds-示例表中显示的内容表示我计算后要使用的ds。您能帮助我理解这种方法是如何在where子句中定义ds的吗?在我看来,它仍然在同一个窗口内工作,也就是说,取正在进行的行的总和,其中每一行的ds是不同的。我们的想法是,我们可以将month和ds列视为参数,即从tableA中选择sum(Quaty),其中ds=一旦它从@month value对3行进行求和,它将结束并移动到下一行Feb等。如果您提供的解决方案确实做到了这一点,您是否可以通过SQL Fiddle或类似工具提供演示?