运行 从最小值到当月的总计

Running Total from minimum to current month

我有两个表,其中一个表包含购买 ID 和购买金额的月份。另一个带日历的。我需要找到当前月份的 运行 总计以及缺少的月份。我尝试了以下查询,但没有得到正确的结果。不确定它是否可能在单个查询中。能不能推荐一下。

输入:销售额

输入:日历

我需要找到 运行 总数,如下所示。

输出:

QUERY 已尝试

  SELECT PID,b.CALMONTH,SUM("AMOUNT") OVER(PARTITION BY "PID" ORDER BY a."YEAR_MONTH") running_total
  FROM SALES a RIGHT JOIN (SELECT YEAR_MONTH  CALMONTH FROM CALENDAR
                           WHERE  CALMONTH BETWEEN '201901' and TO_CHAR(CURRENT_TIMESTAMP,'YYYYMM')) b
  ON a.CALMONTH=b.CALMONTH
  

您可以使用以下查询来获得您想要的结果。祝你好运。

with SalesData as(
select t.pid,t.year_month,sales.amount from 
(select c.year_month,ps.pid from calendar c,
(select distinct pid from sales)ps)t 
left join sales  on t.pid=sales.pid and t.year_month=sales.year_month 
), results as (
SELECT pid,to_date(year_month,'YYYY-MM')as yearmonth, SUM(amount)  
OVER( partition by pid ORDER BY to_date(year_month,'YYYY-MM') 
ROWS BETWEEN UNBOUNDED PRECEDING
AND CURRENT ROW) as amount
FROM SalesData )

select * from results where amount>0 order by pid,yearmonth

我建议将 pid 与月份交叉连接以生成行。然后用一个left join把数据和一个累加起来。

其实很简单:

select p.pid, c.year_month,
       sum(s.amount) over (partition by p.pid order by c.year_month) as running_amount
from (select pid, min(year_month) as min_year_month
      from sales
      group by pid
     ) p cross join
     calendar c left join
     sales s
     on s.pid = p.pid and s.year_month = c.year_month   
where c.year_month >= p.min_year_month 
order by p.pid, c.year_month;

如果您已经有一个日历 table,并且您想要(或必须)使用它,您可以利用连接的“数据致密化”功能,称为“分区外连接”,如如下所示。

with
  prep (pid, year_month, cumulative_amount) as (
    select s.pid, year_month, 
           sum(s.amount) over (partition by s.pid order by year_month)
    from   calendar c left join sales s partition by (pid) using (year_month)
  )
select pid, year_month, cumulative_amount
from   prep
where  cumulative_amount is not null
order  by pid, year_month
;

PID YEAR_MONTH CUMULATIVE_AMOUNT
--- ---------- -----------------
  1 202010                   100
  1 202011                   100
  1 202012                   150
  1 202101                   150
  2 202011                    75
  2 202012                    75
  2 202101                   125

注意 parition by (pid) 子句紧跟在 left join 子句之后。这意味着 sales table 被划分为单独的(且不相交的)子 tables,每个不同的 pid 值一个;分别为这些子 table 中的每一个执行“左连接”,然后将结果与 union all.

的逻辑等价物放在一起

其余部分是标准的 - 使用分析 sum 函数计算累积金额,并在外部查询中过滤掉每个 pid 的“第一个 YM”之前的行 - 您可以识别那些微不足道,因为他们将有 null 累计金额。