我的下表包含了除黄色之外的所有列
基本上,该表格包含客户的ID,销售日期以及当天客户支出的总金额(销售额)。现在,我必须计算当天每位客户的累计销售额,包括当天的销售额。例如,将时间范围设置为3天客户2233购买两次(14日没有),因此他在15日的累计销售额为26,而在13日他们是25。
我无法创建新表,因此我尝试了这种方法,但速度很慢
SELECT t.dt,
Count(CASE WHEN t.running_sale < 1.99 THEN 1 ELSE NULL END) as "Low spender",
Count(CASE WHEN t.running_sale BETWEEN 1.99 and 4.99 THEN 1 ELSE NULL END) as "Medium spender",
Count(CASE WHEN t.running_sale > 4.99 THEN 1 ELSE NULL END) as "High spender"
FROM ( SELECT dt, channel, id, (
SELECT SUM(revenue)
FROM myTable rd
WHERE CAST(rd.dt AS DATE)
BETWEEN (CAST(rd.dt AS DATE) - INTERVAL '3' DAY) AND CAST(rd.dt AS DATE) AND
rd.id = r.id
) running_sale from myTable r) t
WHERE channel = 'retail'
AND dt BETWEEN '2017-06-01' AND '2017-06-15'
GROUP BY dt
limit 100
答案 0 :(得分:2)
我会使用子查询来实现这个
select *,
(
select sum(sales)
from your_table dd
where cast(dd.dates as date)
between cast(your_table.dates as date) - interval '3' day and
cast(your_table.dates as date) and
dd.id = your_table.id
) running_sales
from your_table
并且可以将上述查询重写为更有效的对应方,只需使用自联接和group by
select dd.id, dd.dates, dd.sales, sum(d.sales) running_sales
from your_table dd
join your_table d on cast(d.dates as date)
between (cast(dd.dates as date) - interval '3' day) and cast(dd.dates as date) and
dd.id = d.id
group by dd.id, dd.dates, dd.sales
您可以考虑创建以下索引以支持上述查询:
create index ix_your_table on your_table(id, dates, sales)
答案 1 :(得分:0)
With CTE as (
SELECT 1234 id, '2017-06-15' idate,9 sales from dual UNION ALL
SELECT 2233 id, '2017-06-03' idate,20 sales from dual UNION ALL
SELECT 2233 id , '2017-06-05' idate,4 sales from dual UNION ALL
SELECT 2233 id , '2017-06-06' idate,1 sales from dual UNION ALL
SELECT 2233 id , '2017-06-11' idate,8 sales from dual UNION ALL
SELECT 2233 id , '2017-06-12' idate,4 sales from dual UNION ALL
SELECT 2233 id, '2017-06-13' idate,21 sales from dual UNION ALL
SELECT 2233 id, '2017-06-15' idate,1 sales from dual UNION ALL
SELECT 2544 id , '2017-06-13' idate,9 sales from dual UNION ALL
SELECT 2443 id, '2017-06-05' idate,3.5 sales from dual )
,cte2 as (
select cte.*, to_number(replace(idate,'-')) datekey from cte
)
--select * from cte2
--SELECT cte.*, sum(cte.Sales) OVER (PARTITION by ID ORDER BY cte.iDate asc ROWS 2 PRECEDING ) as RunningSales FROM CTE
--select rownum rn from dual connect by prior
,pp as (
SELECT to_number(dd+20170600) dkey
FROM ( SELECT rownum dd
FROM dual
CONNECT BY LEVEL <= 31
)
)
--select * from pp
,cc as (
select cte2.* ,pp.dkey
from pp left join cte2
on(cte2.datekey=pp.dkey)
)
select cc.* ,sum(cc.Sales) OVER (PARTITION by cc.ID ORDER BY cc.dkey asc ROWS 2 PRECEDING ) as RunningSales
from cc order by dkey asc ,id asc
答案 2 :(得分:0)
如果每天最多只有一次销售,那么最有效的方法可能会重复滞后:
select rd.*,
(sales +
(case when prev_date >= date - interval '2 day' then prev_sales else 0 end) +
(case when prev2_date >= date - interval '2 day' then prev2_sales else 0 end)
) as sales_3day
from (select rd.*,
lag(date, 1) over (partition by id order by date) as prev_date,
lag(date, 2) over (partition by id order by date) as prev_date2,
lag(sales, 1) over (partition by id order by date) as prev_sales,
lag(sales, 2) over (partition by id order by date) as prev_sales2
from mytable rd
) rd;
获得此值后,其余部分只是结果的条件逻辑。
如果您在一个日期有多个销售,则可以通过在最里面的查询中进行汇总来轻松完成此工作。