相对于上一年的历史日期的销售数量

时间:2018-07-06 08:34:45

标签: sql sql-server tsql

我有一个包含销售交易记录的数据库。这些格式为以下(简化)格式:

sales_id | customer_id | sales_date | number_of_units | total_price

我的查询目标是针对每笔交易,以获取该特定customer_id在当前记录之前,在该数据库的整个历史记录中以及在当前记录之前的365天内进行的销售数量。

终身销售现在可以正常进行,但是最近365天的工作使我陷入了困境。现在,我的查询可以确定如果某条记录在过去365天内至少有一笔交易,我这样做是这样的:

SELECT sales_id ,customer_id,sales_date,number_of_units,total_price,
    ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY sales_date ASC) as 'LifeTimeSales' ,
    CASE WHEN DATEDIFF(DAY,sales_date,LAG(sales_date, 1) OVER (PARTITION BY customer_id ORDER BY sales_date ASC)) > -365
         THEN 1 ELSE 0 END as 'Last365Sales'
 FROM sales_db

+一些不重要的WHERE子句。之后,我以其他方式汇总此查询的结果。

但是,这不能告诉我该购买是否是例如客户在过去365天中的第四次销售。

注意: 该查询每天在具有600万条记录并不断增长的完整数据库上运行。我现在删除并重新创建该表,这显然效率不高。当有新的销售进来时更新表是理想的,但是现在这不可能创建。有什么想法吗?

一些测试数据:

sales_id,customer_id,sales_date,number_of_units,total_price
1001,2001,2016-01-01,1,86
1002,2001,2016-08-01,3,98
1003,2001,2017-06-01,2,87
1004,2002,2017-06-01,2,15

+预期结果:

sales_id,customer_id,sales_date,number_of_units,total_price,LifeTimeSales,Last365Sales
1001,2001,2016-01-01,1,86,0,0
1002,2001,2016-08-01,3,98,1,1
1003,2001,2017-06-01,2,87,2,1
1004,2002,2017-06-01,2,15,0,0

2 个答案:

答案 0 :(得分:1)

对于销售之前的销售数量,您可以使用相关的子查询。

SELECT s1.sales_id,
       s1.customer_id,
       s1.sales_date,
       s1.number_of_units,
       s1.total_price,
       (SELECT count(*)
               FROM sales_db s2
               WHERE s2.customer_id = s1.customer_id
                     AND s2.sales_date <= s1.sales_date) - 1 lifetimesales,
       (SELECT count(*)
               FROM sales_db s2
               WHERE s2.customer_id = s1.customer_id
                     AND s2.sales_date <= s1.sales_date
                     AND s2.sales_date >= dateadd(day, s1.sales_date, -356)) - 1 last365sales
       FROM sales_db s1;

(我使用了s2.sales_date <= s1.sales_date,然后从重用中减去了1,因此,如果存在这样的数据,则也可以计算同一天的多次销售。但是由于这也计算了当前行的销售,必须减1。)

答案 1 :(得分:0)

我创建报告视图,其中所有必填字段均可用。 选择您需要的所有内容:

with all_history_statistics as 
(select customer_id, sales_id, sales_date, number_of_units, total_price,
    max(sales_date) over (partition by customer_id order by (select null)) as last_sale_date,
    count(sales_id) over (partition by customer_id order by (select null)) total_number_of_sales,
    count(sales_id) over (partition by customer_id order by sales_date asc ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) number_of_sales_for_current_date,
    sum(number_of_units) over (partition by customer_id order by (select null)) total_number_saled_units,
    sum(number_of_units) over (partition by customer_id order by sales_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) number_saled_units_for_current_date,
    sum(total_price) over (partition by customer_id order by (select null)) as total_earned,
    sum(total_price) over (partition by customer_id order by sales_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) earned_for_current_date)
from sales_db),
with last_year_statistics as 
(select customer_id, sales_id, sales_date, number_of_units, total_price,
    max(sales_date) over (partition by customer_id order by (select null)) as last_sale_date,
    count(sales_id) over (partition by customer_id order by (select null)) total_number_of_sales,
    count(sales_id) over (partition by customer_id order by sales_date asc ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) number_of_sales_for_current_date,
    sum(number_of_units) over (partition by customer_id order by (select null)) total_number_saled_units,
    sum(number_of_units) over (partition by customer_id order by sales_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) number_saled_units_for_current_date,
    sum(total_price) over (partition by customer_id order by (select null)) as total_earned,
    sum(total_price) over (partition by customer_id order by sales_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) earned_for_current_date)
from sales_db)
select <specify list of fields which you need>
from all_history_statistics t1 inner join last_year_statistics
on t1.customer_id = t2.cutomer_id 
;